Znajdź i obróć

30

Zadanie

To proste wyzwanie. Dane wejściowe to pojedynczy niepusty ciąg zawierający tylko cyfry 0123456789i skróty #. Będzie zawierał dokładnie jeden ciąg cyfr, który koduje nieujemną liczbę całkowitą i może owijać się na końcu łańcucha, i co najmniej jeden #. Liczba całkowita może mieć zera na początku. Na przykład ##44##, 013####i 23###1są ważne wejścia, natomiast ###, 0099a #4#4nie są.

Twoim zadaniem jest wyodrębnienie liczby całkowitej nz łańcucha i wyprowadzenie łańcucha obróconego o nkrok w prawo.

Przykłady

  • Dane wejściowe #1##należy obrócić o 1 krok w prawo, aby uzyskać prawidłowe wyjście ##1#.
  • Wejście #026###należy obrócić o 26 kroków w prawo, ponieważ wiodące 0 jest ignorowane. Prawidłowe wyjście to 26####0.
  • Dane wejściowe 1####2zawierają liczbę całkowitą 21 owiniętą na końcu, dlatego należy ją obrócić o 21 kroków w prawo. Prawidłowe wyjście to ##21##.

Zasady i punktacja

Możesz napisać pełny program lub funkcję. Wygrywa najniższa liczba bajtów, a standardowe luki są niedozwolone.

Możesz założyć, że liczba npasuje do standardowego inttypu Twojego języka. I odwrotnie, jeśli ten inttyp standardowy implementuje liczby całkowite o dowolnej dokładności, musisz (teoretycznie) obsługiwać dowolną dużą liczbę n.

Przypadki testowe

#1## -> ##1#
##4## -> #4###
1####1 -> ####11
1####2 -> ##21##
#026### -> 26####0
#000### -> #000###
###82399 -> ##82399#
51379#97 -> #9751379
#98##### -> ###98###
#######4## -> #4########
60752#1183 -> 8360752#11
####99366800## -> 366800######99
########9##### -> ###9##########
91#####515694837 -> 1#####5156948379
###6114558###### -> #6114558########
######219088736090042#### -> 9088736090042##########21
#46055080150577874656291186550000138168########### -> 0138168############4605508015057787465629118655000
568375993099127531613012513406622393034741346840434468680494753262730615610086255892915828812820699971764142551702608639695081452206500085233149468399533981039485419872101852######################3680 -> 99533981039485419872101852######################36805683759930991275316130125134066223930347413468404344686804947532627306156100862558929158288128206999717641425517026086396950814522065000852331494683
Zgarb
źródło
7
Czy musimy obsługiwać wszystkie przypadki testowe? Niektóre z tych liczb są dość duże ... Czy użycie języka z 8-bitowymi liczbami całkowitymi byłoby dopuszczalne?
Dennis
@ Dennis Możliwe jest rozwiązanie problemu za pomocą arytmetyki modułowej bez wczytywania liczby całkowitej do pamięci ... ale masz rację, w wielu językach jest to problem. Załóżmy, że musisz obsługiwać tylko te przypadki testowe, w których npasuje do rodzimego inttypu języka (co może być dowolną precyzją). Zaktualizuję tekst wyzwania później.
Zgarb
Co powinniśmy zrobić, jeśli input = 1234?
CalculatorFeline
2
@CatsAreFluffy ”i co najmniej jeden #”
FryAmTheEggman

Odpowiedzi:

10

CJam, 11 bajtów

q_'#%W%sim>

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Zauważ, że to nie zadziała dla dwóch ostatnich przypadków testowych, ponieważ zaangażowane liczby nie pasują do 64 bitów.

Jak to działa

q_          e# Read all input and push it twice.
  '#%       e# Split at runs of '#'.
     W%     e# Reverse the resulting array.
       si   e# Cast to string, then to int.
         m> e# Rotate the original input that many places to the right.
Dennis
źródło
Oooh ... takie proste!
Luis Mendo
7

Julia, 71 65 bajtów

s->join(circshift([s...],maximum(parse,split(s*s,"#",keep=1<0))))

Jest to anonimowa funkcja, która przyjmuje ciąg i zwraca ciąg. Aby go wywołać, przypisz go do zmiennej.

Dołączamy dane wejściowe do siebie, dzielimy je na tablicę #jako separator, analizujemy każdą liczbę całkowitą i przyjmujemy maksimum. Określa liczbę przesunięć łańcucha w prawo. Splatamy sznurek w Chartablicę, przesuwamy i z joinpowrotem razem.

Alex A.
źródło
7

Python, 66 bajtów

lambda l:(2*l)[-int(''.join(l.split('#')[::-1]))%len(l):][:len(l)]
Lynn
źródło
5

Siatkówka oka, 65 57 49

(\ d *) # * (\ d +)
2 USD 1 USD 0 USD
^ \ d +
$ *
+ `1 (. *) (.)
 2 USD 1 USD
<spacja>

Zaoszczędź 8 bajtów dzięki Martinowi!

Wypróbuj online!

Zauważ, że skończy się to czas / zabraknie pamięci dla bardzo dużych przypadków testowych online i na większości rozsądnych maszyn, dla niektórych większych.

Pobiera ostatnią liczbę w ciągu i pierwszą lub brak liczby w ciągu i umieszcza je przed ciągiem. Następnie konwertuje tę połączoną liczbę na jednoargumentową i wielokrotnie obraca się, jednocześnie upuszczając jednoargumentową cyfrę.

FryAmTheEggman
źródło
3

Galaretka, 12 10 bajtów

ẋ2~ṣ0‘ḌṂṙ@

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

tło

Powiedz, że dane wejściowe to 51379#97.

Powtarzając ciąg dwukrotnie ( 51379#9751379#97), możemy upewnić się, że będzie on zawierał ciągłą reprezentację liczby.

Następnie stosujemy bitowe NIE do wszystkich znaków. Próbuje rzutować na int, więc „1” jest przetwarzane na 1 , a następnie mapowane na ~ 1 = -2 . W przypadku niepowodzenia ( #) zwraca 0 .

W naszym przykładzie to daje

[-6, -2, -4, -8, -10, 0, -10, -8, -6, -2, -4, -8, -10, 0, -10, -8]

Następnie dzielimy na zera, aby oddzielić część, która koduje liczbę od reszty.

[[-6, -2, -4, -8, -10], [-10, -8, -6, -2, -4, -8, -10], [-10, -8]]

Bitowe NIE odwzorowuje n na -n - 1 , więc zwiększamy każde, aby uzyskać -n .

[[-5, -1, -3, -7, -9], [-9, -7, -5, -1, -3, -7, -9], [-9, -7]]

Następnie konwertujemy każdą listę z podstawy 10 na liczbę całkowitą.

[-51379, -9751379, -97]

Najniższa liczba to minus tej, której szukamy. Ponieważ atom rotacji listy żelków obraca się w lewo , pozwala to uniknąć pomnożenia przez -1, aby obrócić w prawo.

Jak to działa

ẋ2~ṣ0‘ḌṂṙ@  Main link. Input: S (string)

ẋ2          Repeat the string twice.
  ~         Apply bitwise NOT to all characters.
            This maps 'n' to ~n = -(n+1) and '# to 0.
   ṣ0       Split at occurrences of zeroes.
     ‘      Increment all single-digit numbers.
      Ḍ     Convert each list from base 10 to integer.
       Ṃ    Take the minimum.
        ṙ@  Rotate S that many places to the left.
Dennis
źródło
3

MATL , 28 25 17 16 bajtów

!G1Y4XXPZcXvUYS!

8 bajtów mniej pożyczenia pomysł Dennisa na podzielenie tablicy i odwrócenie kolejności elementów

Dwa ostatnie przypadki testowe nie działają, ponieważ liczba jest zbyt duża.

EDYCJA (20 maja 2016 r.) Kod w linku używa Xzzamiast z Xvpowodu ostatnich zmian w języku.

Wypróbuj online!

!         % take implicit input: string. Transpose into column char array
G         % push input string again
1Y4       % predefined literal '\d' (for regexp)
XX        % match regexp. Gives cell array with 1 or 2 strings
P         % flip that array
ZcXv      % join the strings in that array, without spaces
U         % convert to number
YS        % rotate the transposed input that many times
!         % put back into row form (string). Implicitly display
Luis Mendo
źródło
2

PowerShell, 153 bajty

(Ale zobacz sekcję Dodatkowy kredyt poniżej)

param($a)$d=[System.collections.arraylist][char[]]$a;for($b=+("$a$a"-split"#"-ne'')[1];$b;$b--){$r=$d[-1];$d.removeAt($d.Count-1);$d.insert(0,$r)}-join$d

PowerShell nie ma pojęcia „przesunięcia” tablicy, więc musiałem stworzyć własne rozwiązanie. Większa liczba zajmie dużo czasu, ale w końcu powinna ukończyć wszystko, co mieści się w 32-bitowej int.

Pobiera dane wejściowe $ai ustawia nową zmienną $djako obiekt [System.Collections.ArrayList] . Odbywa się to, ponieważ technicznie tablice w PowerShell są niezmienne (wyjaśnione poniżej w Dodatkowym kredycie) , a zatem nie obsługują arbitralnych wstawiania lub usuwania, które są potrzebne do zmiany. Następnie wchodzimy w forpętlę.

Pierwszy warunek to sztuczka, którą znalazłem - jeśli połączymy dane wejściowe razem, podzielimy #i zignorujemy opróżnienia, drugi element wynikowej tablicy będzie równy naszej liczbie, niezależnie od zawijania. Ustawiamy to na $bi zmniejszamy za $bkażdym razem, aż wyniesie zero.

W każdej iteracji ustawiamy pomocnika $rjako ostatni element na liście arraylist, usuwamy ten ostatni element, a następnie wstawiamy element z przodu ... skutecznie „przesuwając” tablicę w prawo o jeden element.

Wreszcie, po prostu generujemy dane wyjściowe, -join$ddzięki czemu jest ono połączone w jeden ciąg.


Dodatkowy kredyt

Jeśli problemem było przesunięcie tablicy w lewo zamiast w prawo , możemy to zrobić znacznie krócej przy użyciu wielokrotnego przypisania . Zasadniczo „Jeśli wartość przypisania zawiera więcej elementów niż zmiennych, wszystkie pozostałe wartości zostaną przypisane do ostatniej zmiennej”.

Zasadniczo oznacza to coś podobnego $c=@(1,2,3)i $a,$b=$c
będzie zawierało $a=1int i $b=@(2,3)tablicę.

PowerShell, 90 bajtów, wykonuje przesunięcie w lewo zamiast w prawo

param($a)$b=+("$a$a"-split"#"-ne'')[1];$a=[char[]]$a;for(;$b;$b--){$r,$a=$a;$a+=$r}-join$a

Tutaj ponownie przyjmujemy dane wejściowe i ustawiamy $bjak wyżej. Przerzucamy ponownie $ajako tablicę znaków, a następnie wchodzimy w tę samą forpętlę, co powyżej. Tym razem jednak nie musieliśmy wspierać arbitralnego usuwania / wstawiania, więc nie musimy używać kosztownego [System.Collections.ArrayList]obiektu ani kosztownych wywołań metod. Zamiast tego po prostu ustawiamy $rsię na pierwszy element $a, a pozostałe elementy są ponownie zapisywane w $a. Następnie musimy +=przywrócić go do końca.

(Jak powiedziałem, tablice PowerShell są technicznie niezmienne, ale +=operator tutaj jest przeciążony - bierze tablicę i inny obiekt, łączy je razem (termin techniczny) w nową tablicę, zwraca ją i zapisuje jako nazwę zmiennej, i niszczy oryginalna tablica. Funkcjonalnie właśnie dodaliśmy element na końcu tablicy, ale technicznie (i z perspektywy czyszczenia pamięci / usuwania śmieci itp.) jest to zupełnie nowa tablica. To oczywiście może stać się kosztowną operacją jeśli tablica jest duża lub złożona. Z drugiej strony, ponieważ tablice są niezmienne, indeksowanie do nich lub iterowanie nad nimi jest bardzo tanie).

Dane wyjściowe pozostają takie same, z -joininstrukcją, aby przekształcić je w pojedynczy ciąg.

AdmBorkBork
źródło
1

Poważnie, 21 bajtów

,;;+'#@s`≈`MM@#@`/`nΣ

Wypróbuj online!

Ostrzeżenie: to rozwiązanie jest bardzo nieefektywne, więc większe przypadki testowe przekroczą limit czasu dla TIO. Skorzystaj z lokalnego tłumacza.

Wyjaśnienie:

,;;+'#@s`≈`MM@#@`/`nΣ
,;;+                   make 3 copies of input, and concatenate two of them
    '#@s               split on #s
        `≈`MM          convert strings to ints, take maximum
             @#@       explode final copy of input
                `/`n   rotate to the right n times
                    Σ  join
Mego
źródło
Concat i weź maksimum: świetny pomysł!
Luis Mendo
@LuisMendo Cieszyłem się, że odpowiedź Alexa pojawiła się przy tej samej strategii, kiedy pisałem tutaj wyjaśnienie.
Mego
Wygląda na to, że jedynym, który początkowo stosował naiwne podejście, byłam ja :-) (obracając początkowy ciąg znaków, aż wszystkie cyfry będą ciągłe)
Luis Mendo
1

Mathematica, 69 bajtów

#~StringRotateRight~ToExpression[""<>Reverse@TextCases[#,"Number"]]&

Znajdź sekwencje liczb w, jeśli są 2, ich kolejność musi zostać odwrócona. Połącz ciągi znaków (jeśli jest to tylko jeden, po prostu zwraca ciąg liczbowy). Przekształć ciąg na numeryczny i obróć go tyle razy.

IPoiler
źródło
FromDigitsdziała zamiast ToExpression.
CalculatorFeline
1

Pyth, 22 14 bajtów

.>zs-.<zxz\#\#

Wypróbuj tutaj!

Wyjaśnienie

.> zs -. <zxz \ # \ # # z = input

     . <z # obróć z w lewo o
        xz \ # # indeks pierwszego wystąpienia skrótu
                  # zapewnia to, że liczba całkowita nie jest owinięta wokół końca
    - \ # # odfiltruj wszystkie skróty
   s # rzutowany na liczbę całkowitą, usuwa również wiodące zera
.> z # wykonaj ostatnią wędrówkę ciągu wejściowego i wydrukuj go

Działa to dla wszystkich przypadków testowych, a także prawie natychmiast kończy się dla bardzo dużych liczb.

Denker
źródło
Możesz zrobić -...\#zamiast h:..."\d+"1. Ponadto, nie trzeba konwertować zna listę znaków, .>działa również na ciąg znaków.
Jakube,
@Jakube Dzięki za podpowiedź, byłem dość zmęczony, kiedy to zrobiłem. ^^
Denker,
1

JavaScript (ES6) 66

Po raz %użyteczny jest głupi minus javascript dla liczb ujemnych

z=>(z+z).substr(-(l=z.length,[a,b]=z.match(/\d+/g),b?b+a:a)%l-l,l)
edc65
źródło
1
@WashingtonGuedes nie, suma w b+ajest łączeniem łańcuchowym. a='32',b='1', (b?b+a:a)=='132', (b|0+a)==33
edc65
1

Pyth, 10 bajtów

.>zss_cz\#

Wypróbuj online. Zestaw testowy.

To jest tłumaczenie odpowiedzi Dennisa na CJam . Robię z niej wiki społeczności, ponieważ nie wymyśliłem tego.

Wyjaśnienie

      cz\#   split input at #
     _       reverse
    s        join
   s         cast to integer
.>z          rotate input right
rev Pietu1998
źródło
1

JavaScript (ES6), 67 64 bajtów

s=>(l=s.length,s+s).substr(l-s.split(/#+/).reverse().join``%l,l)

Kolejny port odpowiedzi Dennisa na CJam.

Edycja: Zapisano 3 bajty, przywłaszczając sobie część odpowiedzi edc65, na którą nie zwracał uwagi.

Neil
źródło
Używając trójki i sumy zamiast reverse ().
Join
@Downgoat Przepraszam, ostatnio mam je głównie w porządku, ale zrobiłem to późno w nocy, więc nie myślałem.
Neil,
@ edc65 Nie, dzięki temu mój wynik był wyższy. s+sZamiast tego skopiowałem lewę. (Właściwie to myślałem o ostatniej nocy, ale byłem zbyt zmęczony, żeby to wypróbować w tym czasie.)
Neil
1

Perl 5, 41 bajtów

39 bajtów plus dwa dla -lFflag ( -M5.01jest bezpłatny):perl -lF -M5.01 script.pl

/#+/;map{unshift@F,pop@F}1..$'.$`;say@F

Wyjaśnienie:

  • -lFodczytuje dane wejściowe, usuwa końcowy $_znak nowej linii, umieszcza resztę w ciągu , dzieli ją na znaki i umieszcza ją w tablicy @F.
  • /#+/znajduje pierwszy ciąg #s $_i ustawia wartość $`równą rzeczy przed nim i $'równą rzeczy po niej. Jeśli $`jest pusty, $'może zawierać więcej #s. Jednak $'.$`to ciąg, którego początkowe podciąg jest kilka razy obrócić tablicę.
  • Teraz tworzymy listę 1..$'.$`, która traktuje $'.$`jako liczbę całkowitą, a tym samym ją numeruje, co usuwa wszystkie końcowe #s, więc lista jest od 1liczby razy, aby obrócić tablicę.
  • Dla każdego elementu na tej liście obracamy tablicę ( popostatni element i unshiftna początek).
  • Następnie saywszystkie elementy obróconego układu.
msh210
źródło
1

Rubinowy - 68 72 70 bajtów

s=ARGV[0]
p s.split(//).rotate(-(s+s).scan(/\d+/).map(&:to_i).max)*""
  • split konwertuje ciąg znaków na tablicę
  • (s+s).scan(/\d+/) konkatenuj ciąg do siebie i uzyskaj tablicę liczb (jako ciągi)
  • map(&:to_i) konwertuje ciągi znaków na ints
  • max wybierz największą int
  • rotate max czasy
  • *""przekonwertować tablicę z powrotem na ciąg (skrót od join)

Stosowanie : ruby scriptname.rb "[string]"

FuzzyTree
źródło
jestem tu nowy. jaka jest etykieta zamieszczania wielu odpowiedzi w różnych językach? Dodałem osobną odpowiedź na wypadek, gdyby jedna była błędna. jeśli dodawanie wielu odpowiedzi nie jest w porządku, daj mi znać, a ja to
usunę
1
Wiele odpowiedzi w różnych językach jest w porządku, a nawet zalecane (pod warunkiem, że wszystkie są poprawne).
Zgarb
0

05AB1E , 14 13 bajtów

Cóż, bardzo mało prawdopodobne jest, aby kod zakończył się dla liczb większych niż 100000, ale jeśli będziesz wystarczająco cierpliwy, pojawi się wyjście :). Kod:

'#¡rJ¹sF¤rS\J

Wyjaśnienie:

'#¡             # Split the input on '#'
   r            # Reverse the stack
    J           # Join the stack
     ¹          # Take the first input
      s         # Swap with the number
       F        # For N in range(0, number), do...
        ¤       #   Obtain the last character
         r      #   Reverse the stack
          S     #   Split everything to individual characters
           \    #   Delete the last character
            J   #   Join the stack

Wypróbuj online!

Wykorzystuje kodowanie CP-1252

Adnan
źródło
0

VBSCRIPT, 82 99 BYTES

poprzedni kod nie obsługiwał spraw z liczbą zawiniętą na końcu

b=len(a):f=replace(a,"#","/",1,1):c=replace(split(f&f,"/")(1),"#",d) mod b:d=right(a,c)&left(a,b-c)

UNGOLFED

b=len(a)                                 -a->implicit input, get its length 
f=replace(a,"#","/",1,1)  -replace first instance of # so we can split later
c=replace(split(f&f,"/")(1),"#",d) mod b    -get the number and calc the mod
d=right(a,c)&left(a,b-c)                    -d->implicit output

to trochę do bani ... prawdopodobnie jest to lepszy sposób, nawet w VBscript

Traceur
źródło
Witamy w Programowaniu łamigłówek i wymianie stosów kodów golfowych. Odpowiedź można poprawić, dodając podział kodu i objaśnienie poniżej kodu golfowego. Czy można również zapisać bajty, tworząc funkcję zamiast programu, gdzie ajest funkcja wejściowa i zwraca wynik? W ten sposób nie będziesz potrzebować połączeń inputboxi msgbox.
wizzwizz4
Dlaczego musisz b?
CalculatorFeline
0

Mathematica, 73 58 bajtów

#~StringRotateRight~Max[FromDigits/@StringSplit[#<>#,"#"]]&

Dużo bajtów. 15 bajtów zapisywane dzięki do IPoiler

CalculatorFeline
źródło
StringRotateRightzapisuje tutaj kilka bajtów.
IPoiler
0

Matlab (73)

  @(a)regexprep(a,'(\d*)#*(\d*)#*','${circshift($0,[0 str2num([$2 $1])])}')
  • Używa innego podejścia, zastanawiam się, czy @luis go użył, ponieważ odnosząc się do jego opisu, są pewne wspólne cechy, podczas gdy (nie)? Na szczęście nie rozumiem przyciętego języka Matl.
Abr001am
źródło
0

matlab (86) 72

 @(n)circshift(n,[0 str2num(circshift(n(n~='#'),[0,-find(n=='#',1)+1]))])
  • Funkcja sumuje ciąg dwa razy, raz dla wyodrębnienia liczb całkowitych, drugi dla żądanego zadania, nie zajmuje to zbyt wiele czasu, ponieważ Matlab obraca się dalej, (Dim)modulus(Length)z tą różnicą, że ulega awarii segmentacji dla większych zakresów.

  • Będzie walczyć, jak grać w golfa bardziej ....


(86)

  @(n)circshift(n,[0 str2num([strtok(n(find(n=='#',1,'last'):end),'#') strtok(n,'#')])])
  • Różnica między tą funkcją a poprzednią, ta łączy dwa odległe wystąpienia liczb całkowitych do tyłu, podczas gdy pierwsza po prostu ją obraca.
Abr001am
źródło