배경
MQTT (Message Queuing Telemetry Transport)는 ISO 표준 발행-구독 기반 메시징 프로토콜 ( Wikipedia )입니다.
각 메시지에는 다음 예와 같은 주제가 있습니다.
myhome/groundfloor/livingroom/temperature
USA/California/San Francisco/Silicon Valley
5ff4a2ce-e485-40f4-826c-b1a5d81be9b6/status
Germany/Bavaria/car/2382340923453/latitude
MQTT 클라이언트는 와일드 카드를 사용하여 메시지 주제를 구독 할 수 있습니다.
- 단일 레벨 :
+
- 모든 레벨 이후 :
#
예를 들어, 서브 스크립 션 myhome/groundfloor/+/temperature
은 다음과 같은 결과를 생성합니다 (굵지 않은 굵은 체 ).
✅ myhome / groundfloor / 거실 / 온도
✅ myhome / groundfloor / 주방 / 온도
❌ myhome / groundfloor / 거실 / 명도
❌ myhome / firstfloor / 거실 / 온도
❌ 차고 / groundfloor / 냉장고 / 온도
구독 +/groundfloor/#
은 다음과 같은 결과를 생성합니다.
✅ 인 MyHome / groundfloor에 / 거실 / 온도
✅ 인 MyHome / groundfloor에 / 부엌 / 밝기
✅ 주차장 / groundfloor에 / 냉장고 / 온도 / 이상 / 별 / 필드
❌ 인 MyHome / firstfloor / 거실 / 온도
❌ 인 MyHome / 지하 / 코너 / 온도
자세한 내용은 여기를 참조하십시오 .
작업
두 개의 문자열을 수락하고 부울을 리턴하는 함수 / 프로그램을 구현하십시오. 첫 번째 문자열은 주제 주제이고 두 번째 문자열은 기준 주제입니다. 기준 주제는 위에서 자세히 설명한 구독 구문을 사용합니다. 주제가 기준과 일치 할 때 기능은 진실합니다.
이 작업에 대한 규칙 :
- 주제는 ASCII입니다
#
와일드 카드 이외의 기준 필드가 없습니다- 와일드 카드는 주제 주제에 나타나지 않습니다
- 주제 필드 수> = 기준 필드 수
- 0 자 필드 나 선행 또는 후행 슬래시가 없습니다.
테스트 사례
기준 1 = “myhome / groundfloor / + / 온도”
기준 2 = “+ / groundfloor / #”
( “abc”, “ab”) => false
( “abc”, “abc”) => true
( “abc / de”, “abc”) => false
( “myhome / groundfloor / livingroom / temperature”, 기준 1 ) => true
( “myhome / groundfloor / 부엌 / 온도”, 기준 1) => true
( “myhome / groundfloor / 거실 / 밝기”, 기준 1) => false
( “myhome / firstfloor / 거실 / 온도”, 기준 1) = > false
( “차고 / 지상층 / 냉장고 / 온도”, 기준 1) => false
( “myhome / 지상층 / 거실 / 온도”, 기준 2) => true
( “myhome / 지상층 / 주방 / 밝기”, 기준 2) => true
( “차고 / 지상층 / 냉장고 / 온도 / 기타 / 특정 / 필드 “, 기준 2) => true
(“myhome / 1 층 / 거실 / 온도 “, 기준 2) => 거짓
( “myhome / 지하실 / 코너 / 온도”, 기준 2) => false
( “music / kei $ ha / latest”, “+ / kei $ ha / +”) => true
답변
젤리 , 20 바이트
ṣ€”/ZṖF”#eƊ¿œiÐḟ”+ZE
문자리스트의 목록을 받아들이는 모나드 링크, [topic, pattern]
어느 반환 1
또는 0
일치 또는 각각 불일치합니다.
온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오.
어떻게?
ṣ€”/ZṖF”#eƊ¿œiÐḟ”+ZE - Link: list of lists of characters, [topic, pattern]
€ - for each:
ṣ - split at occurrences of:
”/ - '/' character
Z - transpose (any excess of topic is kept)
¿ - while...
Ɗ - ...condition: last three links as a monad:
”# - '#' character
e - exists in:
F - flatten
Ṗ - ...do: pop the tail off
Ðḟ - filter discard those for which:
œi - first multi-dimensional index of: ([] if not found, which is falsey)
”+ - '+' character
Z - transpose
E - all equal?
답변
루비 , 65 바이트
정규식 솔루션. 나는 Regex.escape
기준 이름이 그렇게 com.java/string[]/\n
정규식 조각을 가질 만한 것과 같 거나 어리석은 경우가 있다고 덧붙였다 .
->s,c{s=~/^#{Regexp.escape(c).sub('\#','.*').gsub'\+','[^/]*'}$/}
비정규 솔루션, 77 바이트
멋진 간단한 분할, 우편 및 일치 기술을 사용합니다. Regex.escape
정규식 솔루션 을 사용하더라도 어쨌든 짧을 것이라는 것을 깨닫기 전에이 것을 먼저 개발했습니다 .
->s,c{s.split(?/).zip(c.split ?/).all?{|i,j|i==j||'+#'[j||9]||!j&&c[-1]==?#}}
답변
답변
파이썬 3 , 72 바이트
lambda a,b:bool(re.match(b.translate({43:"[^/]+",35:".+"}),a))
import re
이 문제는 정규식 일치로 간단하게 단순화 할 수 있지만 더 흥미로운 다른 방법으로 더 나은 결과를 얻을 수 있습니다.
편집 정규식을 사용하지 않는 107 바이트 솔루션을 생각해 냈습니다. 그것이 72보다 짧아 질 수 있는지 또는 아마도 이것에 대한 올바른 접근법을 보지 못할 수도 있습니다. 분할 지퍼 구조 만 너무 큰 것 같습니다. 온라인으로 사용해보십시오!
답변
파이썬 2 , 85 84 80 92 89 바이트
lambda s,c:all(x in('+','#',y)for x,y in zip(c.split('/')+[0]*-c.find('#'),s.split('/')))
버그를 지적 해준 Jonathan Allan 과 Value Ink 에게 감사합니다 .
답변
하스켈, 76 73 71 67 바이트
(a:b)#(c:d)=a=='+'&&b#snd(span(/='/')d)||a=='#'||a==c&&b#d
a#b=a==b
편집 : @cole 덕분에 -4 바이트.