MQTT 구독 주제 일치 같은 주제가 있습니다. myhome/groundfloor/livingroom/temperature USA/California/San Francisco/Silicon Valley 5ff4a2ce-e485-40f4-826c-b1a5d81be9b6/status Germany/Bavaria/car/2382340923453/latitude MQTT 클라이언트는 와일드

배경

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]==?#}}

온라인으로 사용해보십시오!


답변

펄 5 -pl , 50 바이트

$_="\Q$_";s|\\\+|[^/]+|g;s/\\\#/.*/;$_=<>=~m|^$_$|

온라인으로 사용해보십시오!


답변

파이썬 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 AllanValue 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 바이트.


답변

Clojure에서 , 107 91 76 65 102 바이트

익명 함수는 주제 주제를 진실하고 nil거짓으로 클로저 (유효한 Clojure) 로 반환합니다 .

(defn ?[t c](every? #(#{"#""+"(% 0)}(% 1))(apply #(map vector % %2)(map #(re-seq #"[^/]+" %) [t c]))))

107 (102) 작동
(91) (76) (65)는 모든 문자 정규식 격파