Błędy bez smaku i inne


52

Niektóre wersje standardowej aplikacji kalkulatora na Androida umożliwiają naciśnięcie klawisza, na przykład „sin”, a następnie klawisza „del”, aby uczynić go „si”. Prawdopodobnie tylko błąd, którego usunięcie nie może im przeszkadzać.

Zrzut ekranu kalkulatora Androida

Można wpisać następujące litery / grupy liter:

 

grzech
si
s
sałata
współ
do
dębnik
ta
t
ln
l
log
lo
mi

Tak więc „bez smaku” można pisać na maszynie, ponieważ nie ma smaku, podobnie jak „zatyka się”, ponieważ „c-log-s”. Jednak „got” nie jest możliwe do wpisania, ani „an”, ani „xyz”.

Napisz program, który jako dane wejściowe przyjmuje pojedyncze słowo (lub sekwencję liter, tylko az na wejściu) i generuje dane wyjściowe wskazujące, czy słowo można pisać, czy nie.

Dane wyjściowe mogą być pojedynczymi znakami / literami / cyframi itp. lub może być większy. Wszystkie pisane słowa powinny dawać ten sam wynik. Wszystkie słowa, których nie można wpisać, powinny również generować ten sam wynik.

PS Z ciekawości, czy „bez smaku” jest najdłuższym słowem słownikowym, które można pisać?


1
Żeby było jasne: wypisujemy jedną, spójną cyfrę lub literę, którą wybieramy, aby wskazać, że słowo jest możliwe do wpisania, a inną, pojedynczą, spójną cyfrę lub literę, którą wybieramy, aby wskazać, że słowo nie można wpisać. Czy to jest poprawne?
Dennis,

3
Najdłuższe słowo, jakie udało mi się znaleźć, to 10 liter, koelostaty .
Conor O'Brien

1
Czy więc „πe” nie jest słowem?
Pan Lister,

@Dennis Ya, mniej więcej.
ghosts_in_the_code

1
Kolejne 11: firmy
Chris H

Odpowiedzi:


20

Perl, 47 43 41 + 1 = 42 bajty

-4 bajty dzięki @Sunny Pun. -2 bajty dzięki @Brad Gilbert b2gills i @Downgoat

Uruchom z -nflagą.

say!/^(s(in?)?|co?|t(an?)?|ln?|log?|e)+$/

Z pewnością można grać w golfa później, ale w duchu rywalizacji pozostawiam głównie oryginalne wyrażenia, które wymyśliłem na początku. Nic nie zwraca, jeśli jest prawdziwe, 1jeśli fałszywe.

Wypróbuj online!

Pobrałem plik słownika, a najdłuższe znalezione słowo zawierało 11 liter - tattletales


1
Myślę, że co?powinno wystarczyć, ponieważ sinzajmie się s:) Miłej zabawy /log?/!
Sunny Pun

1
Nie mówi, że musi być rozróżniana iwielkość liter (usuń ) lub że pojedynczy wynik musi mieć sens (usuń jeden !)
Brad Gilbert b2gills

Czy potrzebujesz flagi I na samym końcu, ponieważ dane wejściowe to tylko az?
Downgoat,

Możesz to uprościć: -2: /^(s|sin?|co?|t|tan?|ln?|log?|e)+$/lub jeśli wolisz:/^([celst]|sin?|co|tan?|ln|log?)+$/
Nie żeby Charles

1
Ciesz się nagrodą!
ghosts_in_the_code

16

JavaScript (ES6), 44 bajty

s=>/^((si|ta|l)n?|co?|log?|[ste])+$/.test(s)

Myślę, że jest to najkrótszy możliwy regex, ale oczywiście mogę się mylić.

Wyjaśnienie

Oczywistym pierwszym miejscem na początek byłoby wyrażenie regularne, które po prostu zawiera wszystkie opcje osobno:

s=>/^(sin|si|s|cos|co|c|tan|ta|t|log|lo|l|ln|e)+$/.test(s)

Po pierwsze, możemy zaobserwować, że cosmożna je utworzyć z coi s, co czyni go niepotrzebnym:

s=>/^(sin|si|s|co|c|tan|ta|t|log|lo|l|ln|e)+$/.test(s)

Niektóre z nich, takie jak sini si, można łączyć, czyniąc ostatnią literę opcjonalną:

s=>/^(sin?|s|co?|tan?|t|log?|ln?|e)+$/.test(s)

Działa to, ponieważ sin?dopasowuje siz lub bez nna końcu, w ten sposób obejmując oba sini si.

Wydaje się, że jest też dużo n?s. Co jeśli połączymy je wszystkie razem?

s=>/^((si|ta|l)n?|s|co?|t|log?|e)+$/.test(s)

Jeszcze jednym sposobem na golfa byłoby połączenie pozostałych opcji jednoznakowych w zakres postaci, ale pojawia się to na tej samej długości:

s=>/^((si|ta|l)n?|co?|log?|[ste])+$/.test(s)

I w ten sposób grasz w prosty zwrot regularny. Uważam, że jest to najkrótszy możliwy regex, który pasuje do każdego łańcucha poprawnie, ale być może nie. Będę przyznać +100 nagrodę dla każdego, kto udaje się poprawić na tym regex.


Ten, którego użyłem w swojej odpowiedzi, jest podobny:^(s|t|co?|(l|ta|si)n?|log?|e)+$
Mama Fun Roll

Po pierwsze, liczę 44 bajty. Po drugie, oto alternatywny ale już rozwiązanie: / /.test.bind(/^((si|ta|l)n?|co?|log?|[ste])+$/).
Conor O'Brien

@ ConorO'Brien Ups, nie wiem, jak to
przeliczyłem

Możesz zrobić a=/^((si|ta|l)n?|co?|log?|[ste])+$/;a.testdla 42 bajtów. Wierzę, że jest to dozwolone, ponieważ a.testjest to funkcja anonimowa.
NoOneIsHere

@SeeOneRhino Jest, ale tak naprawdę nie jest to dozwolone, ponieważ f=a.testnie działa. Zastanawiam się, czy można zadzwonić z alternatywną nazwą a.test...
ETHproductions

7

Pyth, 37 33 29 28 bajtów

Kod zawiera znak niedrukowalny, więc oto xxdzrzut heksowy.

00000000: 737d 5173 4d5e 733c 5252 6336 2e22 6174  s}QsM^s<RRc6."at
00000010: 14d0 69ba 76f1 ac59 6422 346c            ..i.v..Yd"4l

Wypróbuj online.

Niezwykle nieefektywny astronomicznie. Złożoność czasu i przestrzeni wynosi O (16 n ) O (24 n ).

Wyjaśnienie

Po pierwsze, Qdodaje się domyślnie a.

s}QsM^s<RRc6."…"4lQ     Implicit: Q = input
            ."…"        Generate "logsincostanlnee"
          c6            Split in 6 parts: ["log", "sin", "cos", "tan", "ln", "ee"]
         R      4       For each n from 0 to 3
       <R               Take the first n chars from each string
      s                 Flatten the results
                 lQ     Get length of input
     ^                  Take that Cartesian power of the list
   sM                   Join each resulting list
 }Q                     Check if the input is found
s                       Cast to integer

PO wyjaśnił; nie potrzebujesz s.
Dennis,

6

Galaretka , 32 31 30 28 26 bajtów

ŒṖw@€€“¡Ṡ[ẈKœịḲ-¢ȧ?-»’%3ḌẠ

Zwraca 0, jeśli słowo można wpisać, 1 jeśli nie. Dzięki @JonathanAllan za grę w golfa na 1 bajcie!

Wypróbuj online!

Jak to działa

ŒṖw@€€“¡Ṡ[ẈKœịḲ-¢ȧ?-»’%3ḌẠ  Main link. Argument: s (string of lowercase letters)

ŒṖ                          Yield all partitions of s.
      “¡Ṡ[ẈKœịḲ-¢ȧ?-»       Yield "sine  logcostanln". Every third character
                            marks the start of a typeable word.
  w@€€                      Find the indices of all substrings in the partitions
                            in the string to the right (1-based, 0 if not found).
                     ’      Decrement. "Good" indices are now multiples of 3.
                      %3    Modulo 3. "Good" indices are mapped to 0, "bad"
                            indices are mapped to 1 or 2.
                        Ḍ   Convert from decimal to integer. A partition will
                            yield 0 iff all indices are "good".
                         Ạ  All; yield 0 if one or more integers are falsy (0), 1
                            if all integers are truthy (non-zero).

6

Brachylog , 33 bajty

Naprawiono błąd dzięki @Synoli.

~c:1a
,"sincostanloglneeee"@6e@[?

Wypróbuj online!

Dane wyjściowe, true.jeśli można je wpisać lub false.inaczej.

Wyjaśnienie

Próbujemy dekonkatenacji danych wejściowych, dopóki nie znajdziemy takiej, dla której wszystkie łańcuchy, które konkatenujemy, są przedrostkiem jednego z nich ["sin", "cos", "tan", "log", "lne", "eee].

~c                          A list of strings which when concatenated results in the Input
  :1a                       All strings of this list satisfy the predicate below:

,"sincostanloglneeee"@5           The list ["sin", "cos", "tan", "log", "lne", "eee"]
                       e          Take one element of that list
                        @[?       The input is a prefix of that element

Dlaczego .po true?
Kritixi Lithos

1
@KritixiLithos W SWI-Prolog, gdy zapytanie jest prawdziwe, drukuje się true.i false.inaczej. Właśnie to zaimplementowałem: jeśli dane wyjściowe są ignorowane (tak jak tutaj) i nie ma zapisu do STDOUT, to zostanie wydrukowane true.lub w false.zależności od tego, czy główny predykat się powiedzie, czy nie. Ma kropkę SWI-Prolog bo true.i false.są rzeczywiście ważne programy, które zawsze udaje / zawsze kończy się niepowodzeniem.
Fatalize

Jak działa to rozwiązanie bez tanwyraźnego pojawienia się na liście?
Synoli,

2
@Synoli Nie. Naprawiłem to kosztem 3 bajtów, dzięki.
Fatalize

4

Perl 6 ,  60 50  44 bajtów

pierwsza próba ( 60 )

put +?(get~~/^<{<sin cos tan ln log e>».&{|m:ex/^.+/}}>*$/)

tłumaczenie odpowiedzi Perla 5 ( 50 )

put +?(get~~/^[s[in?]?|co?|t[an?]?|ln?|log?|e]*$/)

za pomocą -nprzełącznika ( 43 + 1 )

put +?/^[s[in?]?|co?|t[an?]?|ln?|log?|e]*$/

Pierwszy ?konwertuje wynik na wartość logiczną, a pierwszy +konwertuje go na liczbę ( 1for True, 0for False)


3

Mathematica, 101 bajtów

If[StringMatchQ[#,("sin"|"si"|"s"|"cos"|"co"|"c"|"tan"|"ta"|"t"|"ln"|"l"|"log"|"lo"|"e")..],"T","F"]&

Wydaje się, że najtrudniejszymi częściami tego wyzwania są najkrótsze wyrażenia regularne i wybór najbardziej zwięzłego języka odpowiadającego wyrażeniu regularnemu. Nie mam nic wspólnego z tym pierwszym, a Mathematica nie jest dobrym kandydatem na to drugie, ponieważ musisz użyć StringMatchQi RegularExpression. Mogę odpowiedzieć na twoje PS: czy „bez smaku” jest najdłuższym słowem, które możesz wpisać?

In[1]:= f=StringMatchQ[#,("sin"|"si"|"s"|"cos"|"co"|"c"|"tan"|"ta"|"t"|"ln"|"l"|"log"|"lo"|"e")..]&;

In[2]:= Select[EntityList@"Word",f@#[[2,1]]&][[All,2,1]]//SortBy[StringLength]//DeleteDuplicates
Out[2]= {c,e,l,s,t,cc,cl,el,et,lo,si,sl,ta,te,ccc,col,cos,cot,eel,ell,eta,etc,lee,let,log,lot,sec,see,set,sic,sin,sit,tae,tan,tat,tec,tee,cell,clog,clot,coco,cole,colt,coss,cost,cote,else,less,loco,loge,loll,lose,loss,lota,sect,seel,sell,sess,seta,sett,sill,silo,silt,sine,sise,siss,site,sloe,slog,slot,stet,taco,tact,tael,talc,tale,tall,tect,tell,test,cello,close,cosec,costa,cotan,eccle,elect,elsin,ettle,loess,lotte,secle,setee,since,sleet,stale,stall,state,steel,stele,tasse,taste,tatee,teest,telco,testa,tetel,tsine,cellco,closet,coleta,collet,coltan,cosine,cosset,costal,ecesis,estate,lessee,scelet,select,sellee,sestet,settee,settle,siesta,silole,stacte,stance,stasis,tallet,tallot,taslet,tassel,tasset,tattle,tectal,teetan,tellee,testee,tsetse,celesta,cessile,cocotte,collect,costate,ecolect,ectasis,electee,sessile,sinless,sitelet,statant,tassell,tastant,testate,coestate,colessee,colocolo,cosiness,costless,electant,lossless,sceletal,siletane,statelet,tactless,tallness,telltale,telocoel,coelostat,sissiness,stateless,tasteless,tattletale}

Tak więc „tattletale” wydaje się być najdłuższym według jednej postaci.


Dlaczego to nie konkuruje? Czy funkcja f was nie definiują zgodne z zasadami wyzwanie?
Dennis,

Nie, to wysyła Truelub Falsezamiast pojedynczego znaku.
ngenisis,

Posty oznaczone problemem decyzyjnym dotyczą określenia Prawda / Fałsz, więc myślę, że to konkuruje.
FlipTack,

Status niekonkurujący jest zarezerwowany dla zgłoszeń, które używają języka lub funkcji języka, która nie istniała lub zawierała błąd w momencie opublikowania wyzwania.
Dennis,

Słusznie. Zredagowałem swoją odpowiedź, aby znaleźć rzeczywiste rozwiązanie.
ngenisis,

2

Zastanawiam się , 41 bajtów

!.(mstr"^(s|t|co?|(l|ta|si)n?|log?|e)+$")

Stosowanie:

(!.(mstr"^(s|t|co?|(l|ta|si)n?|log?|e)+$")) "tasteless"

Zupełnie źle zrozumiałem pytanie, ale teraz wszystko zostało naprawione. Wyjścia Fdla dopasowania i Tbez dopasowania.

Niekonkurencyjne, 35 bajtów

!.`^(s|t|co?|(l|ta|si)n?|log?|e)+$`

Stosowanie:

(!.`^(s|t|co?|(l|ta|si)n?|log?|e)+$`) "tasteless"

Wykorzystuje to odpowiednie wyrażenia regularne, które zostały wdrożone po tym wyzwaniu.


2
Z mojego zrozumienia, możesz usunąć tylko ostatni znak z kalkulatora, co oznacza, że nnie można go wpisać, ale sini lnjest.
Sunny Pun

Ten wyrażenie regularne wykrywa sajako prawdę
Kritixi Lithos,

1
To nie powiedzie się w przypadku testowym got.
Dennis,

Myślę, że to naprawione.
Mama Fun Roll

?Aby ekspresja sub uległe; zobacz rexegg.com/regex-quantifiers.html#cheat_sheet . Ale nawet uczynienie go chciwym ??lub zaborczym z ?+jakiegoś powodu nie działa (przynajmniej w PHP). coelostatswyzwala pułapkę (at loi ta).
Tytus,

2

Przetwarzanie, 223 bajty

int d(String b){for(String p:"tan0log0sin0cos0ln0e".split("0"))if(p.startsWith(b))return 1;return 0;}

int l(String p){String b="";int t=1;for(char c:p.toCharArray()){b+=c;if(d(b)<1){b=c+"";t=d(b);}if(t<1)return t;}return t;}

W końcu zdecydowałem się odpowiedzieć bez wyrażenia regularnego. Aby wywołać funkcję, użyj l("tasteless");. Zwraca 0za false i 1za true.

Rozszerzony kod z objaśnieniem

int d(String b){
  for(String p:"tan0log0sin0cos0ln0e".split("0"))
    if(p.startsWith(b))
      return 1;
  return 0;
}
//main function
int l(String p){
  String b="";
  int t=1;
  for(char c:p.toCharArray()){
    b+=c;
    if(d(b)<1){
      b=c+"";
      t=d(b);
    }
    if(t<1)return t;
  }
  return t;
}

Zasadniczo, iterujemy po danym ciągu, budując bznak po znaku. Możemy sprawdzić za pomocą d()jeśli którekolwiek z tan, log... zacząć b. Jeśli tak, to jest ważny. W przeciwnym razie sprawdzamy, czy znak na tej pozycji jest prawidłowy i resetujemy b. Teraz, jeśli jest nieprawidłowy, 0zostanie zwrócony, w przeciwnym razie nadal będzie ważny. Na koniec, jeśli program jeszcze czegoś nie zwrócił, to wróć 1.


Czy dfunkcja nie może zwrócić znaku bool?
Roman Gräf,

@ RomanGräf Używa więcej bajtów booleanniż int. Również truei falsewymagają więcej bajtów niż 1i0
Kritixi Lithos

2

Scala, 49 bajtów

s=>s.matches("(s(in?)?|co?|t(an?)?|ln?|log?|e)+")

Zwraca true, jeśli podany ciąg pasuje do wyrażenia regularnego, w przeciwnym razie false.


2

Python 3 , 154 bajtów

r=1;i=input()
while r:
 r=0
 for s in'sin,cos,tan,log,ln,co,lo,si,ta,s,c,t,l,e'.split(','):
  if i.startswith(s):r=i=i.replace(s,'',1);break
print(i=='')

Wypróbuj online!


1
Może być konieczne sprawdzenie wcięcia, musiałem edytować kod, aby działał
George

@george, dziwne, próbowałem w IDLE i kompilatorze online i oba wydają się działać
Henke

2

Python 3 , 149 130 bajtów

i=input()
for a in 'tan,sin,cos,log,si,co,ta,lo,lo,ln,s,c,t,l,e'.split(','):
    if a in i:
        i=i.replace(a,"")
print(not i)

edycja nr 1: ogolono 19 bajtów przy użyciu rozwiązania @Henke


0

Python 2, 124 bajty

f=lambda w:any(f(w[len(s):])if w[:len(s)]==s else 0for s in'sin,cos,tan,log,ln,co,lo,si,ta,s,c,t,l,e'.split(','))if w else 1

0

PHP, 60 bajtów

<?=preg_match("#^((si|ta|l)n?|co?|log?|s|e|t)+$#",$argv[1]);

regex skradziony z ETHproductions :
pobiera dane wejściowe z argumentu wiersza poleceń; Wydruki 1dla oznaczalnych izolatów, 0dla nie typeable.

starsze wersje, 75 73 69 bajtów

<?=!preg_replace("#co|log|ln|lo|sin|si|tan|ta|[celst]#","",$argv[1]);

zastępuje wszystkie możliwe słowa pustym ciągiem, zwraca wynik, neguje.

<?=!preg_split("#co|log|ln|lo|sin|si|tan|ta|[celst]#",$argv[1],-1,1);

dzieli dane wejściowe według wyrażeń regularnych. Flaga 1oznacza PREG_SPLIT_NO_EMPTYi mówi, preg_splitaby zwracać tylko niepuste wyniki. Jeśli dane wejściowe są możliwe do wpisania, preg_splitbędą mieć tylko puste wyniki, więc zwróci pustą tablicę, co jest fałszem. !neguje wynik.

Obie wersje pobierają dane z argumentu wiersza poleceń
i wypisują, 1jeśli wynik jest pusty (dane wejściowe można wpisać), w przeciwnym razie nic.

Uwagi:
Pakowanie wyrażenia regularnego ?nie działa tutaj; sprawia, że ​​wyrażenia są pozbawione wyrazu; prawdopodobnie z powodu cofania się. Kolejność alternatyw jest ważna: tamusi stać przed, talbo silnik przestanie się dopasowywać, gdy znajdzie t.

Znalazłem ściągacz kwantyfikatora , pomyślałem ??lub ?+może pomóc; ale dla mnie nie działały.


0

Java 8, 55 bajtów

s->return s.matches("^((si|ta|l)n?|co?|log?|[ste])+$");

Disclamer: Kiedyś ETHproductions' regex, ponieważ było wiele bajtów krócej niż kopalnia. Pełne uznanie dla Regexa. Dodałem 24 bajty, aby uczynić ją funkcją Java.

Zwraca, falsejeśli słowo nie pasuje do Regex, w przeciwnym razie true.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.