Czy 7 l8r niż 9? (Czy siódma jest później niż dziewiąta?)

10

Jest to dość proste wyzwanie golfowe. Twój program, mając ciąg ASCII, parsuje ten ciąg na dwa ciągi, które oceni. Jeśli drugi ciąg jest „późniejszy” niż pierwszy, zwróci 1, jeśli jest „wcześniejszy” niż pierwszy, zwróci -1, a jeśli są takie same, zwróci 0. To wyjaśnij, co oznaczają „później” i „wcześniej”, spójrzmy na kody znaków ASCII. Musisz porównać każdy znak ciągu, traktując każdy z nich jako cyfry liczby. Później odnosi się do większej liczby, występującej po mniejszej liczbie. Ciągi zostaną sformatowane za pomocą znaku łącznika, aby oddzielić dwie grupy wejściowe.

Spójrz na ten przykład:

7-9jako dane wejściowe powinny powrócić 1.

7konwertuje na kod ASCII 55i 9konwertuje na kod ASCII 57.

Jak 57następuje numerycznie po 55, 9jest późniejszy niż 7.

Inny przykład:

LKzb-LKaj jako dane wejściowe powinny powrócić -1

Sekwencjami kodu ASCII do tego są 76-75-122-98i76-75-97-106

Jest to wyzwanie dla golfa kodowego, a liczba bajtów określa sposób punktowania wpisów.

Dowolne dane wejściowe z 95 drukowalnych znaków ASCII są akceptowane, z wyjątkiem spacji i łączników dla wszystkiego oprócz oddzielenia danych wejściowych. Ponadto nie można zagwarantować, że ciągi są tej samej długości.

Powodzenia!

EDYCJA: Aby być bardziej zrozumiałym, każdy znak należy traktować jak cyfrę w liczbie. W tym przykładzie LKzb-LKaj, choć jjest późniejszy niż b, zjest późniejszy a, a ponieważ jest to cyfra bardziej znacząca, ma pierwszeństwo. Podany ciąg będzie zawsze miał co najmniej 3 znaki, co wyeliminuje puste ciągi z zakresu tego problemu.

EDYCJA: Oto kilka przypadków testowych, do twojej pomocy:

  • A-9 -> -1
  • 11-Z -> -1
  • 3h~J*-3h~J* -> 0
  • Xv-Y0 -> 1
Sam Weaver
źródło
1
Czy obie struny mają taką samą długość?
es1024
5
Przypadek testowy 11-Z-> -1nie ma sensu, biorąc pod uwagę obecne sformułowanie pytania. Z(90) jest większy niż 1(49) i jest najbardziej znaczącą literą. Wyjaśnij, w jaki sposób porównywane są łańcuchy o różnych długościach.
George Reith,
2
A co A-AA?
2
@SamWeaver Wiem, że najbardziej na lewo jest najważniejsza cyfra, stąd moje zamieszanie co do tego, dlaczego 11>Zw twoich przykładach kiedy 1<Z. Musi istnieć pewne niezdefiniowane zachowanie związane z łańcuchami o różnych długościach lub przykład jest zły.
George Reith,
3
Jak wyjaśniono wcześniej: każdy ciąg należy traktować jako cyfrę w liczbie podstawowej 127. Jeśli miałbyś liczyć w tym systemie, zacznij od znaku, zwiększaj go do bariery znaków do wydrukowania, ~na 126, a następnie zwiększaj kolejną cyfrę o jedną, zwracając początkową cyfrę do !. Każdy wzrost najbardziej znaczącej cyfry odpowiada inkrementacji drugiej najbardziej znaczącej cyfry o 127.
Sam Weaver

Odpowiedzi:

11

Pyth - 11 bajtów

Łatwy, używa ._znaku, aby uzyskać znak i Cuzyskać kody znaków .

._-F_CMcz\-

Wypróbuj online tutaj .

Zestaw testowy .

._               Sign of number
 -F              Fold subtraction (this finds difference of a tuple)
  _              Reverse list to get correct order of operands when subtracting
   CM            Map char, already treats strings as digits of base256 number
    c \-         Split by "-"
     z           Input
Maltysen
źródło
Bardzo dobrze! Wykonuje się zgodnie z oczekiwaniami.
Sam Weaver,
7

CJam, 12 bajtów

l'-/esfb~\-g

Wypróbuj online w interpretatorze CJam .

Jak to działa

l   e# Read a line from STDIN.
'-/ e# Split it at spaces.
es  e# Push the current time (milliseconds since epoch).
fb  e# Consider each string as digits in base huge-number.
~\  e# Dump the results and reverse their order.
-g  e# Subtract and apply sign function.
Dennis
źródło
Świetny! To przechodzi wszystkie przypadki testowe.
Sam Weaver,
6

Java, 86 118

int f(String...s){return(int)Math.signum((s=s[0].split("-"))[1].compareTo(s[0])*(s[0].length()==s[1].length()?1:-1));}  

Bardzo dziwny sposób porównywania ciągów. Dokonano szybkiej poprawki, więc przechodzi dodatkowe przypadki testowe, później będzie szukał golfa.

Dzięki Vartan w komentarzach za signumsugestie

Geobity
źródło
Czy i tak porównanie java zwraca 1,0, -1? Wiem, że nie ma takiej gwarancji, ale czy jest jakiś przypadek, że nie? w takim przypadkureturn s[0].compareTo(s[1]);
Vartan
To miłe, ale nie przechodzi w testowy przypadek 11-Zpowrotu -1, zwraca 1.
Sam Weaver,
Ach, nie było to dla mnie jasne przed dodaniem tych przypadków testowych. Naprawiony.
Geobits
@Vartan Nie, zwraca różnicę wartości na pierwszej niepasującej pozycji (lub różnicę długości, jeśli występuje jeden i wszystkie znaki pasują). Na przykład "A".compareTo("Z") zwraca-25 . Niestety.
Geobits
Czy możesz wyjaśnić tę linię? i = a!=b ? b-a : s[1].compareTo(s[0]);Wydaje mi się, że nie rozumiem ... Może możesz użyć Math.signum i uratować się deklarując i;
Vartan
4

Perl, 31 bajtów

#!/usr/bin/perl -p
/-/;$_=($`.$'^$`)cmp($'.$`^$')

30 bajtów + 1 bajt dla -p. Akceptuje dane wejściowe STDIN.

Wyjaśnienie

Gdy operandy cmpmają różne długości, takie jak chickeni egg, są wyrównane w następujący sposób:

c  h  i  c  k  e  n
e  g  g  \0 \0 \0 \0

więc egg> chicken( \0jest bajtem zerowym). Ale chcemy, aby były one wyrównane w następujący sposób:

c  h  i  c  k  e  n
\0 \0 \0 \0 e  g  g

tak, że chicken> egg.

Aby to zrobić, łączymy je, raz chickenprzed eggi raz eggprzed chicken:

c  h  i  c  k  e  n  e  g  g
e  g  g  c  h  i  c  k  e  n

Teraz, gdy nasze dwa ciągi są tej samej długości, usuwamy wiodące słowo za pomocą XOR, aby uzyskać:

\0 \0 \0 \0 \0 \0 \0 e  g  g
\0 \0 \0 c  h  i  c  k  e  n

A teraz możemy użyć, cmpaby znaleźć, co było pierwsze. (Tam powiedziałem!)

ThisSuitIsBlackNot
źródło
Bardzo sprytnie - Brawo!
Sam Weaver,
3

Python 2, 88 znaków

a=raw_input().split('-');print-cmp(*(map(ord,s.rjust(max(map(len,a)),'\0'))for s in a))

cmpnie robi tego dobrze, gdy masz dwa łańcuchy o różnych długościach, więc muszę wypełnić oba je znakiem null (który ordkonwertuje na 0), aby obsłużyć tę sprawę. Niestety, dodało to około 35 znaków, a teraz są teraz dwie linie zamiast jednej, ponieważ potrzebuję zarówno długości danych wejściowych, jak i iteracji.

Alex Van Liew
źródło
Niestety nie jest to prawidłowe rozwiązanie. Następujący przypadek testowy:, 1-2który powinien zwrócić 1zwraca -1. Sprytna praca.
Sam Weaver,
Ups, wygląda na to, że operandy są zamienione. To bardzo dziwne, przetestowałem to na kilku twoich testowych przypadkach i pomyślałem, że działa dobrze! Bez względu na to, mogę to zmienić bez zmiany liczby postaci. Spróbuj teraz.
Alex Van Liew
Twoja edycja naprawiła tę sprawę, ale teraz nie powiedzie się 11-A, która powinna zwrócić -1, zamiast zwracać 1w tym przykładzie.
Sam Weaver,
Nie podoba mi się twoje zasady dotyczące długości. Naprawiłem to kosztem około 35 znaków i nie sądzę, żebym mógł to poprawić.
Alex Van Liew
1
Udało mi się uzyskać krótszą odpowiedź niż twoja, kodując ciąg do formatu szesnastkowego, a następnie analizując ten ciąg jako liczbę całkowitą. W Pythonie 2 wydaje się, że domyślnie jest to big-endianness. Zatem wypełnienie 0 nie jest już wymagane.
Wydmy,
2

R, 54 bajtów

Wymaga to biblioteki pracma. Dzieli ciąg wejściowy na -. Prawo uzasadnia ciągi. Ranguje je i robi różnicę.

Tak więc dla 11-7 otrzymujemy ciągi „11” i „7”. Ich ranga to [2, 1]. Różnica wynosi -1. Dla 3h ~ J * -3h ~ J * otrzymujemy „3h ~ J *” i „3h ~ J *”. Ich ranga to [1,5, 1,5] z różnicą 0.

diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))

Przykłady testowe

> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: LKzb-LKaj
3: 
Read 2 items
[1] -1
> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: A-9
3: 
Read 2 items
[1] -1
> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: 11-Z
3: 
Read 2 items
[1] -1
> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: 3h~J*-3h~J*
3: 
Read 2 items
[1] 0
> diff(rank(pracma::strjust(scan(,'',sep='-'),"right")))
1: Xv-Y0
3: 
Read 2 items
[1] 1
MickyT
źródło
Sprytny. Dobra robota :)
Alex A.,
2

CoffeeScript, 143 140 139

f=(s)->[a,b]=((t=s.split '-').map (y)->Array((m=Math.max) 1, 1+(m ((l=(c)->c.length) t[0]),l t[1])-l y).join('\u0000')+y);`b<a?-1:(b>a?1:0)`

Oto jsfiddle z wynikami (spójrz w konsolę)

danielrw7
źródło
2

PERL, 46 36 bajtów

print$2cmp$1if"@ARGV"=~/(\S+)-(\S+)/

Konwertuje listę argumentów na ciąg znaków, dzieli myślnik na lewy i prawy argument bez spacji, a następnie zwraca wywołanie cmp.

Eric
źródło
Podejrzewam, że możesz pozbyć się wielu spacji i;
MickyT,
Powinien być w stanie uciec: "@ARGV"=~/-/;print$`cmp$' (niesprawdzony)
Jarmex
1
Dobry pomysł na użycie cmp, ale nie działa, gdy długości łańcuchów są różne. "A" cmp "9"wynosi 1, podczas gdy "11" cmp "Z"wynosi -1, chociaż oba wejścia powinny zwrócić tę samą wartość dla tego wyzwania.
ThisSuitIsBlackNot
1

Python 3, 84 bajtów

x,y=[int.from_bytes(i.encode(),"big")for i in input().split("-")];print((x<y)-(y<x))

Podziel ciąg znaków przez "-". Konwertuj ciągi Unicode na ciągi bajtów, a następnie interpretuj te ciągi bajtów jako liczby całkowite big-endian. Na koniec dokonaj porównania - (nie) na szczęście cmpnie jest już dostępne w Pythonie 3.

Python 2, 69 bajtów

print -cmp(*[int(i.encode("hex"),16)for i in raw_input().split("-")]) 
Wydmy
źródło
Możesz ogolić postać, usuwając spację między printi cmp.
Alex Van Liew
1

Python 2, 79 bajtów

Całkiem proste rozwiązanie i łatwe do zrozumienia. Porównuje długości strun, a następnie porównuje struny leksykograficznie.

Wypróbuj tutaj

s,t=raw_input().split('-')
x,y=len(s),len(t)
print(x<y)*2-1if x-y else cmp(t,s)
mbomb007
źródło
1

perl5, 64

perl -aF- -pe '@f=map{length}@F;$_=$f[1]<=>$f[0]||$F[1]cmp$F[0]'

Po prostu uruchom go z wiersza poleceń. chociaż nowa linia wyglądałaby lepiej, ale kosztuje to 1 znak.

perl -laF- -pe '@f=map{length}@F;$_=$f[1]<=>$f[0]||$F[1]cmp$F[0]'

Ta dłuższa wersja poprawnie obsługuje niedopasowane długości.

Hildred
źródło
/-/,$_=$`cmp$'byłoby łatwiejsze i możesz -aF-trochę pominąć . Ponadto liczę to jako 20 (16 dla $_=$F[1]cmp$F[0]i 4 dla paF-zapisanych w pliku i uruchomionych jako perl -paF- file.pl).
primo
1
Jak zauważyłem w odpowiedzi Erica , cmpnie działa, gdy dwa ciągi mają różną długość, jak w przypadku 11-Z.
ThisSuitIsBlackNot
@ThisSuitIsBlackNot, naprawiony.
Hildred
Miły. Możesz zagrać w golfa do 39 za pomocą /-/;$_=length$'<=>length$`||$' cmp$`i -p. ( $`przechowuje wszystko przed dopasowaniem wyrażenia regularnego, $'przechowuje wszystko później.) Korzystanie z mapfaktycznie kosztuje więcej bajtów niż tylko lengthdwukrotne wywołanie .
ThisSuitIsBlackNot
0

F #, 53

fun s->let[|a;b|]=s="";s.Split[|'-'|]in b.CompareTo a

Ma to postać anonimowej funkcji (lambda), więc musisz ją wkleić i podać parametr bezpośrednio po nim (lub używając notacji potokowej). Na przykład (w FSI):

> "7-9" |> fun s->let[|a;b|]=s="";s.Split[|'-'|]in b.CompareTo a
1
> "abc-abc" |> fun s->let[|a;b|]=s="";s.Split[|'-'|]in b.CompareTo a
0
> "LKzb-LKaj" |> fun s->let[|a;b|]=s="";s.Split[|'-'|]in b.CompareTo a
-1
Jwosty
źródło
0

JavaScript ES6, 46 43 bajtów

f=s=>((a=s.split('-'))[1]>a[0])-(a[1]<a[0])
George Reith
źródło
Dobra robota, ale to nie kończy się przypadek testowy 2: 11-Zpowinien zwrócić, -1ale zwraca 1.
Sam Weaver,
1
@SamWeaver Rzeczywiście, został dodany po odpowiedzi i łamie także inne odpowiedzi. Czy możesz wyjaśnić, dlaczego, '11'>'Z'gdy '11'<'ZZ'nie ma pytania o to, jak porównać ciąg o różnych długościach lub jaką wartość ma pusty ciąg.
George Reith,
Cel pytania nigdy się nie zmienił, dodałem tylko te przypadki testowe i wyjaśnienia, ponieważ zdałem sobie sprawę, że na początku nie byłem wystarczająco jasny. Masz rację, że nigdy nie zdefiniowałem wartości pustego ciągu i odpowiednio zaktualizuję pytanie. Te przypadki testowe nie zmieniły zachowania ani celu pytania, a jedynie je wyjaśniły. Podane przez ciebie przykłady działają jako takie, ponieważ każdy znak musi być traktowany jako pojedyncza „cyfra” w liczbie, której podstawa jest równoważna wszystkim drukowalnym znakom ASCII. Ta mechanika pytania nigdy się nie zmieniła, po prostu stała się bardziej przejrzysta.
Sam Weaver,
1
@SamWeaver Zmiana z niezdefiniowanego zachowania na zdefiniowane zmienia to. Nic nie jest postacią. Chyba że jest to znak zerowy, który to obsługuje.
George Reith,
0

Ruby, 59 bajtów

a,b=gets.chomp.split ?-
p (b.size<=>a.size).nonzero?||b<=>a
daniero
źródło
0

05AB1E , 12 11 9 bajtów

'-¡₄ö¥0.S

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

'-¡          # Split the (implicit) input on '-'
             #  i.e. 'LKzb-LKaj' → ['LKzb','LKaj']
   ₄ö        # Convert both parts to a Base-1000 number
             #  i.e. ['LKzb','LKaj'] → [21020061037,21020036045]
     ¥       # Push the deltas (subtraction between each sub sequential pair) of the list
             #  i.e. [21020061037,21020036045] → [-24992]
      0.S    # Get the sign [1 for a>0; -1 for a<0; 0 for a==0] (and output implicitly)
             #  i.e. [-24992] → [-1]
Kevin Cruijssen
źródło