Liczby jednoargumentowe zwykle reprezentują tylko nieujemne liczby całkowite, ale możemy je rozszerzyć tak, aby reprezentowały wszystkie liczby całkowite w następujący sposób:
- Dodatnia liczba całkowita N jest reprezentowana przez N
1
:5 -> 11111
- Ujemna liczba całkowita -N jest reprezentowana
0
przez następującą po niej literę N1
:-5 -> 011111
- Zero jest reprezentowane jako
0
Następnie możemy jednoznacznie przedstawić listę tych liczb, jeśli użyjemy 0
jako separatora:
3,-2,0,1
111,011,0,1
111 0 011 0 0 0 1
11100110001
Twoje zadanie: weź ciąg reprezentujący taką listę podpisanych liczb jednoargumentowych i przetłumacz go na listę liczb dziesiętnych.
Detale
Możesz założyć, że dane wejściowe to pełna lista podpisanych liczb jednoargumentowych. W szczególności twój program nie będzie musiał obsługiwać 1) pustych danych wejściowych lub 2) danych wejściowych, które kończą się separatorem.
Możesz założyć, że wielkość każdej liczby nie przekroczy 127. W przypadku języków o maksymalnych rozmiarach ciągów lub list możesz założyć, że dane wejściowe i wyjściowe będą pasować do struktur danych Twojego języka, ale Twój algorytm powinien teoretycznie działać dla listy dowolny rozmiar.
Twój program lub funkcja może wykonywać operacje we / wy na dowolny ze standardowych sposobów . Dane wejściowe mogą być ciągiem lub listą znaków, ciągami jednoznakowymi, liczbami całkowitymi lub wartościami logicznymi. Możesz użyć dowolnych dwóch znaków do przedstawienia 1
i 0
; jeśli nie używasz 1
i 0
, określ, jakich znaków używasz.
Dane wyjściowe muszą być liczbami dziesiętnymi w dowolnym rozsądnym formacie listy (w szczególności musi istnieć pewnego rodzaju separator między liczbami). Liczby ujemne powinny być oznaczone znakiem minus, chociaż jeśli twój język ma inny format ujemnych liczb całkowitych, również to zaakceptuję. Zero może być reprezentowane na wyjściu jako 0
lub -0
.
Przypadki testowe
1 -> 1
0 -> 0 (or -0, and similarly for the other test cases)
011 -> -2
1101 -> 2,1
1100 -> 2,0
11001 -> 2,-1
110001 -> 2,0,1
11100110001 -> 3,-2,0,1
00000001 -> 0,0,0,-1
01111011111111001111111111111110111111111111111100111111111111111111111110111111111111111111111111111111111111111111 -> -4,8,-15,16,-23,42
01111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 -> -127
'0's
, nie jest to technicznie jednoznaczne. Dobre wyzwanie!0
) i przedrostek znaku ujemnego (0
) są takie same, chociaż nadal są jednoznaczne, ponieważ nie można mieć znaków ujemnych w środku liczby (czy182--693-1
liczba? Nie, i żadne nie jest1111011000101111
z tego samego powodu).Odpowiedzi:
Python 2 ,
7370 bajtówFunkcja, która pobiera ciąg jako dane wejściowe i zwraca ciąg reprezentujący listę w języku Python. Zero może być reprezentowane zarówno przez, jak
0
i-0
(gdy jest ostatnie):Wyjaśnienie
split
ciąg wejściowys
na zerach.map
).To zajmuje nam długą drogę. Zera były przecież separatorami. A liczby były jedne, więc
len
wygodnie zamienia je na dziesiętne. Ale teraz zawiedliśmy wszystkie zastosowania, które nie są separatorami0
. Na szczęście wszystkie zastosowania bez separatora były zerami wiodącymi, więc pojawiły się po separatorze zero i dały nam ciągi zerowej długości ('00'.split('0') == ['', '', '']
). Te łańcuchy o zerowej długości stały się również0
spowodowane przezlen
.replace
każde zero poprzedzające inną liczbę zamiast znaku minus na tej liczbie. To naprawia użycie0
znaku jako, ale łamie dosłowne zera. Dosłowne zera poprzedzone były również separatorem, więc teraz stały się parami dodatkowych myślników na następnej liczbie.replace
każdy z--
powrotem do0
elementu na „liście”.źródło
Siatkówka ,
2321 bajtówWypróbuj online!
Pierwszy etap
(.)0<newline>$1<space>
odpowiada dowolnej postaci, po której następuje0
. Dopasowanie zostanie zastąpione pierwszym znakiem, a następnie spacją. To dzieli ciąg na poszczególne liczby.Drugi etap
01<newline>-1
zamienia0
przed blokiem1
na-
znak.Ostatni etap
1+<newline>$.&
dopasowuje wszystkie bloki1
i zastępuje je długością grupy.Oto przykład z wynikami poszczególnych etapów.
źródło
Vim, 56 bajtów
Wypróbuj online!
Jakiś czas nie pisałem w vimie. Najczęściej używam vima, ponieważ V jest czasem bólem. Ponieważ
count
polecenie, które idealnie nadaje się do uzyskania liczby „1” w linii, nadpisze wszelkie „0” w linii, więc nie możemy jej później zanegować.Wyjaśnienie:
Jest to jeden bajt krótszy niż prosty sposób:
z powodu łączenia poleceń. Ponieważ ten rozdziela polecenia, użyję go do wyjaśnienia.
Teraz każdy podpisany numer jednoargumentowy znajduje się w osobnej linii. Na przykładzie „11100110001” będziemy w tym momencie:
Ponieważ dodawaliśmy nowe wiersze na końcu każdego meczu, przed uruchomieniem mieliśmy pustą linię. Po uruchomieniu tego otrzymamy „0” (ponieważ pasowało do serii 0 „1”). Więc po prostu dzwonimy,
D
aby usunąć tę linię, pozostawiając ją pustąźródło
:%s/1+$/
dałby ci jeden bajt krótszy, gdyby nie potrzeba odwrotnego ukośnika+
:(-
zamiast0
lub-0
Haskell ,
6866 bajtówWypróbuj online! Pobiera dane wejściowe jako listę zer i jedynek. Przykładowe użycie:
f [0,0,0,1,1]
daje[0,-2]
.Wyjaśnienie:
Dopasowanie wzorca w
f(x:r)|(a,b)<-span(>0)r
wiążex
się z pierwszym elementem danych wejściowych,a
(potencjalnie pustą) listą kolejnych1
s orazb
z resztą danych wejściowych. Biorąc pod uwagę wejście[0,1,1,1,0,0,1]
, otrzymujemyx=0
,a=[1,1,1]
ib=[0,0,1]
.Bieżąca liczba jest wówczas albo sumą
a
zanegowanego ifx=0
, albo sumąa
plus jeden ifx=1
. Osiąga się to poprzez indeksowanie zx
do listy zawierającej funkcję negacji i przyrost i zastosowanie uzyskanego funkcji sumya
:[(0-),(1+)]!!x$sum a
.Lista reszty
b
jest pusta lub zawiera oddzielające zero i następną liczbę. Zrozumienie listy[z|_:t<-[b],z<-f t]
próbuje dopasowaćb
się do wzorca_:t
, to znaczy zapomnieć o elemencie head i powiązać resztę listyt
. Jeślib
jest puste, to dopasowanie kończy się niepowodzeniem, a interpretacja listy ocenia[]
, co jest podstawowym przypadkiem rekurencji. W przeciwnym razie funkcjaf
jest rekurencyjnie stosowana,t
a interpretacja listy ocenia wszystkie elementyz
z wynikuf t
.źródło
Wolfram Language (Mathematica) , 80 bajtów
Wypróbuj online!
Nadużywa mechaniki
StringCases
, ponieważ nie sprawdza nakładających się wzorów. Ponieważ szukamy od lewej do prawej, bez nakładania się, zawsze otrzymujemy tylko liczby całkowite, których potrzebujemy.Wyjaśnienie
Dodaj zero na końcu
Znajdź wszystkie następujące wzory ...
Pojedynczy znak (nazwij go
x
), po którym następuje możliwie najkrótszy ciąg o zerowej długości lub dłuższy (nazwij goy
), po którym następuje zero.Zastosuj do pasującego wzoru: weź długość
y
. Gdybyx
wynosi zero, zaneguj wartość. W przeciwnym razie, zwiększ o jeden.Obejmuje to
00
również, ponieważy
byłby to pusty ciąg znaków i obliczalibyśmy-0
(== 0
).źródło
Brain-Flak , 94 (70?) Bajtów
Wypróbuj online!
Jest to w rzeczywistości zaskakująco zwięzłe, jeśli chodzi o atak mózgu.
Oto skomentowana / czytelna wersja:
Jeśli wyjście może być odwrócone, możemy to zrobić dla 70 zamiast tego:
Ten mój tip jest prawie idealny na tę sytuację. Ale to nie do końca działa, ponieważ musimy nacisnąć 0 przed wykonaniem operacji (licząc „1”), a operacja odbywa się w pętli. Najkrótsze, jakie mogłem wymyślić z wykorzystaniem tej wskazówki, to:
który jest również 94 bajtami.
źródło
Perl 5 , 40 + 1 (
-n
) = 41 bajtówWypróbuj online!
źródło
Łuska ,
20 18 17 1514 bajtówWypróbuj online!
Wyjaśnienie
Podział działa w ten sposób.
ġ/
dzieli swój argument na każdą parę elementów, wa,b
przypadku której/a b
występuje fałsz./a b
to podział z odwróconymi argumentami, więcb
podzielony przeza
. Odpowiednie wartości w tym programie to:/1 1
daje1
(prawda)./1 0
daje0
(fałsz)./0 1
dajeInf
(pozytywna nieskończoność, prawda)./0 0
dajeAny
(specjalna wartość podobna do NaN, fałsz).źródło
Acc !! ,
252237 bajtówZastosowania
-0
. Wyświetla liczby oddzielone znakami tabulacji z tabulatorem końcowym. Wypróbuj online!Ilość czasu na zapisanie faktycznego algorytmu: 20 minut. Czas debugowania mojego dziesiętnego kodu wyjściowego: 45 minut. : ^ P
Z komentarzami
Nie wiem, czy te komentarze bardzo dobrze wyjaśniają kod - opierają się na moich notatkach do siebie, gdy go pisałem, więc zakładają, że rozumieją, jak Acc !! Pracuje. Jeśli coś wymaga więcej wyjaśnień, daj mi znać, a postaram się to wyjaśnić.
źródło
Python 2 ,
9692 bajtówWypróbuj online!
Dzięki za ovs i DLosc za 2 bajty każdy.
źródło
R 119 bajtów
Wypróbuj online!
Kod korzysta z tego rozwiązania z przepełnienia stosu do pokrewnego problemu (dzięki jeales za pomysł). Dane wyjściowe to łańcuch rozdzielany spacjami, drukowany na standardowym wyjściu.
źródło
Galaretka ,
1918 bajtówMusi być lepszy sposób ...
Pełny program drukujący każdą liczbę, a następnie wysuw linii.
Wypróbuj online!
W jaki sposób?
źródło
QBasic,
8886 bajtówTo było fajne. Wiele poprawek, począwszy od wersji 107-bajtowej, zaowocowało jednym z najbardziej zaciemnionych fragmentów QBasic, o których myślę, że kiedykolwiek napisałem.(Edycja: Co dziwne, byłem w stanie zagrać w golfa 2 bajty, czyniąc kod jaśniejszym.)
Uwaga: ten program odczytuje wprowadzane przez użytkownika po jednym znaku bez echa na ekranie (wynik użycia
INPUT$(1)
zamiast zwykłejINPUT
instrukcji). Podczas pisania nie zobaczysz jedynek i jedynek, ale liczby dziesiętne pojawią się w miarę ich obliczania. Pamiętaj, aby trafićEnter na końcu wejścia, aby zobaczyć ostatni numer i zakończyć program.Wersja bez golfa
Wyjaśnienie
(AKA „Co? To wciąż nie ma sensu!”)
Podstawową strategią jest uruchomienie pętli, która za
INPUT$(1)
każdym razem chwyta jedną postać , robi z nią rzeczy i utrzymuje pętlę, dopóki postać ma wartość ASCII większą niż wartość!
(tj. Nie była nową linią).Śledzimy bieżące liczby za pomocą dwóch zmiennych.
num
to liczba znaków w bieżącej podpisanej liczbie jednoargumentowej (w tym dowolne początkowe zero).sign
jest,1
jeśli liczba miała wiodące zero,0
jeśli nie. Oba muszą zostać zainicjowane0
, co jest świetne dla wersji golfowej, ponieważ zmienne numeryczne w QBasic są automatycznie inicjowane0
.Ilekroć czytamy postać, pierwszą rzeczą jest ustalenie, czy jest ona,
1
czy też0
. Wykorzystamy ten wynik dwa razy, więc przechowujemy goisZero
. Technicznie nazwa ta wprowadza w błąd, ponieważ wartość będzie również prawdziwa, jeśli postać będzie nową linią. Zauważ, że prawda w QBasic jest-1
i falsey jest0
.Teraz, gdy jesteśmy w trakcie czytania liczby (
num > 0
) i osiągamy zero lub koniec wejścia (isZero
), musimy obliczyć, którą liczbę już przeczytaliśmy.sign
przechowuje0
pozytywne,1
negatywne. Aby uzyskać1
pozytywne i-1
negatywne, potrzebujemy1-2*sign
.num
przechowuje poprawną jasność dla pozytywów, ale o jedną więcej niż jasność dla negatywów (ponieważ zawiera znacznik znaku). Możemy więc użyćnum-sign
tej wielkości.Pomnóż je razem i wydrukuj; następnie zresetuj
sign
inum
do0
w ramach przygotowań do odczytania następnego numeru.W przeciwnym razie (jeśli nie osiągnęliśmy zera lub jeśli osiągnęliśmy zero na początku liczby), aktualizujemy
sign
inum
postępujemy następująco:sign
staje się,1
gdy patrzymy na wiodące zero; w przeciwnym razie, jeśli patrzymy na jednego, pozostaje on na tym, czym już był. Kod do gry w golfa jests=s-z
taki sam:z
to jest-1
. Ponieważs
gwarantowane jest0
(ponieważ jest to początek nowego numeru),s-z
będzie1
.z
to jest0
. Następnies-z
pozostaje na dowolnejs
wcześniejszej wartości .num
jest zwiększany.Otóż to!
źródło
JavaScript (ES6), 60 bajtów
Zwraca rozdzieloną spacjami listę liczb całkowitych.
Przypadki testowe
Pokaż fragment kodu
źródło
Lua , 58 bajtów
Wypróbuj online!
Pełny program, pobiera dane z wiersza poleceń i wypisuje liczby na standardowe oddzielone nowymi liniami.
źródło