Localize e gire

30

A tarefa

Este é um desafio simples. Sua entrada é uma única string não vazia, contendo apenas dígitos 0123456789e hashes #. Ele conterá exatamente uma sequência de dígitos, que codifica um número inteiro não negativo e pode envolver o final da sequência e pelo menos um #. O número inteiro pode ter zeros à esquerda. Por exemplo, ##44##, 013####e 23###1são entradas válidas, enquanto ###, 0099e #4#4não são.

Sua tarefa é extrair o número inteiro nda sequência e gerar as netapas rotacionadas para a direita.

Exemplos

  • A entrada #1##deve ser girada 1 passo para a direita, para que a saída correta seja ##1#.
  • A entrada #026###deve ser girada 26 etapas para a direita, pois o 0 inicial é ignorado. A saída correta é 26####0.
  • A entrada 1####2contém o número inteiro 21 envolto no final, portanto deve ser girado 21 etapas para a direita. A saída correta é ##21##.

Regras e pontuação

Você pode escrever um programa completo ou uma função. A menor contagem de bytes vence e as brechas padrão não são permitidas.

Você pode assumir que o número nse encaixa no inttipo padrão do seu idioma. Por outro lado, se esse inttipo padrão implementar números inteiros de precisão arbitrária, você deverá suportar (em teoria) um arbitrariamente grande n.

Casos de teste

#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
fonte
7
Temos que suportar todos os casos de teste? Alguns desses números são bem grandes ... Seria aceitável usar um idioma com números inteiros de 8 bits?
Dennis
@Dennis É possível resolver o desafio com aritmética modular sem realmente carregar o número inteiro na memória ... mas você está certo, é um aborrecimento em muitos idiomas. Digamos que você só precise lidar com os casos de teste que nse encaixam no inttipo nativo do seu idioma (que pode ter precisão arbitrária). Atualizarei o texto do desafio mais tarde.
Zgarb
O que devemos fazer se input = 1234?
CalculatorFeline
2
@CatsAreFluffy "e pelo menos um #"
FryAmTheEggman 24/02

Respostas:

10

CJam, 11 bytes

q_'#%W%sim>

Experimente online! ou verifique todos os casos de teste .

Observe que isso não funcionará nos dois últimos casos de teste, pois os números envolvidos não cabem em 64 bits.

Como funciona

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
fonte
Oooh ... tão simples!
Luis Mendo
7

Julia, 71 65 bytes

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

Esta é uma função anônima que aceita uma string e retorna uma string. Para chamá-lo, atribua-o a uma variável.

Anexamos a entrada a ela mesma, dividimos em uma matriz com #o separador, analisamos cada número inteiro e obtemos o máximo. Isso define o número de vezes que mudamos a string para a direita. Dividimos a corda em uma Charmatriz, trocamos e joina juntamos novamente.

Alex A.
fonte
7

Python, 66 bytes

lambda l:(2*l)[-int(''.join(l.split('#')[::-1]))%len(l):][:len(l)]
Lynn
fonte
5

Retina, 65 57 49.

(\ d *) # * (\ d +)
$ 2 $ 1 $ 0
^ \ d +
$ *
+ `1 (. *) (.)
 $ 2 $ 1
<espaço>

Economizou 8 bytes graças a Martin!

Experimente Online!

Observe que isso esgotará o tempo limite / memória para os casos de teste muito grandes on-line e, na maioria das máquinas sãs, para alguns dos maiores.

Isso pega o último número da string e o primeiro ou nenhum número da string e os coloca na frente da string. Em seguida, converte esse número combinado em unário e gira repetidamente enquanto solta um dígito unário.

FryAmTheEggman
fonte
3

Gelatina, 12 10 bytes

ẋ2~ṣ0‘ḌṂṙ@

Experimente online! ou verifique todos os casos de teste .

fundo

Digamos que a entrada seja 51379#97.

Repetindo a string duas vezes ( 51379#9751379#97), podemos garantir que ela contenha uma representação contígua do número.

Em seguida, aplicamos NOT bit a bit a todos os caracteres. Isso tenta converter para int, para que '1' seja avaliado como 1 e , em seguida, mapeado para ~ 1 = -2 . Na falha ( #), ele retorna 0 .

Para o nosso exemplo, isso dá

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

Em seguida, dividimos em zeros para separar a parte que codifica o número do restante.

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

Bitwise NOT mapeia n para -n - 1 , então incrementamos cada um para obter -n .

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

Em seguida, convertemos cada lista da base 10 em número inteiro.

[-51379, -9751379, -97]

O número mais baixo é o negativo do que estamos procurando. Como o átomo de rotação da lista Jelly gira para a esquerda , evite multiplicar por -1 para girar para a direita.

Como funciona

ẋ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
fonte
3

MATL , 28 25 17 16 bytes

!G1Y4XXPZcXvUYS!

8 bytes a menos de empréstimo da idéia de Dennis de dividir a matriz e reverter a ordem das peças

Os dois últimos casos de teste não funcionam porque o número é muito grande.

EDIT (20 de maio de 2016) O código no link usa, em Xzvez de Xv, devido a alterações recentes no idioma.

Experimente 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
fonte
2

PowerShell, 153 bytes

(Mas consulte a seção Crédito extra, abaixo)

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

O PowerShell não tem o conceito de "mudar" uma matriz, então tive que lançar minha própria solução. Levará muito tempo para números maiores, mas acabará por concluir qualquer coisa que se encaixe em um int de 32 bits.

Recebe entrada $ae define uma nova variável $dcomo um objeto [System.Collections.ArrayList] . Isso é feito porque, tecnicamente, as matrizes no PowerShell são imutáveis (mais explicadas abaixo em Crédito Extra) e, portanto, não suportam inserções ou remoções arbitrárias, necessárias para a troca. Então, entramos em um forloop.

A condição inicial é um truque que encontrei - se concatenarmos a entrada juntos, dividirmos #e ignorarmos os vazios, o segundo elemento da matriz resultante será igual ao nosso número, independentemente do agrupamento. Definimos isso como $be diminuímos $bcada vez até que seja zero.

A cada iteração, definimos helper $rcomo o último elemento da lista de matrizes, removemos esse último elemento e inserimos o elemento na frente ... "deslocando" efetivamente a matriz para a direita por um elemento.

Finalmente, simplesmente produzimos com -join$dpara que seja concatenado em uma sequência.


Crédito extra

Se o problema foi deslocar a matriz para a esquerda em vez da direita , podemos reduzi-lo significativamente usando várias atribuições . Basicamente, "Se o valor da atribuição contiver mais elementos que variáveis, todos os valores restantes serão atribuídos à última variável."

Em essência, isso significa algo como $c=@(1,2,3)e $a,$b=$c
terá $a=1um int e $b=@(2,3)um array.

O PowerShell, 90 bytes, faz um desvio à esquerda em vez de um desvio à direita

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

Aqui, mais uma vez, recebemos informações e definimos $bcomo acima. Relançamos $acomo uma matriz de caracteres e inserimos o mesmo forloop acima. Desta vez, porém, não precisamos oferecer suporte à remoção / inserção arbitrária, portanto não precisamos usar o [System.Collections.ArrayList]objeto caro , nem o método caro chama. Em vez disso, simplesmente configuramos $rpara ser o primeiro elemento de $a, e os elementos restantes são salvos novamente $a. Em seguida, vamos +=colocá-lo de volta até o fim.

(Como eu disse, as matrizes do PowerShell são tecnicamente imutáveis, mas o +=operador aqui está sobrecarregado - ela pega uma matriz e outro objeto, junta-os (termo técnico) em uma nova matriz, retorna isso e o salva como o nome da variável e destrói Funcionalmente, acabamos de adicionar um elemento ao final da matriz, mas tecnicamente (e de uma perspectiva de limpeza de memória / lixo etc.) é uma matriz totalmente nova. Isso obviamente pode se tornar uma operação cara se a matriz for grande ou complexa. O outro lado é que, como as matrizes são imutáveis, a indexação ou a iteração sobre elas é muito barata.)

A saída permanece a mesma ação, com uma -joininstrução para transformá-la em uma única sequência.

AdmBorkBork
fonte
1

Sério, 21 bytes

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

Experimente online!

Aviso: esta solução é muito ineficiente; portanto, os casos de teste maiores expirarão no TIO. Use o intérprete local.

Explicação:

,;;+'#@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
fonte
Concat e aproveite ao máximo: ótima idéia!
18606 Luis MendoFev
@LuisMendo Fiquei divertido ao ver a resposta de Alex aparecer com a mesma estratégia enquanto escrevia a explicação aqui.
Mego
Parece que o único que usado inicialmente a abordagem naïve foi me :-) (rodando a cadeia inicial até que todos os dígitos eram contíguos)
Luis Mendo
1

Mathematica, 69 bytes

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

Encontre seqüências de números em, se houver 2, sua ordem precisará ser revertida. Concatene as strings (se for apenas uma, apenas retornará a string numérica). Converta a string em numérico e gire a string esse número de vezes.

IPoiler
fonte
FromDigitsfunciona em vez de ToExpression.
CalculadoraFeline
1

Pyth, 22 14 bytes

.>zs-.<zxz\#\#

Experimente aqui!

Explicação

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

     . <z # gire z para a esquerda por
        xz \ # # índice da primeira ocorrência de um hash
                  # Isso garante que o número inteiro não seja encapsulado no final
    - \ # # filtra todos os hashes
   s # convertido em um número inteiro, também remove os zeros iniciais
.> z # faça a rotação final da sequência de entrada e imprima-a

Isso funciona para todos os casos de teste e também quase termina instantaneamente para grandes números.

Denker
fonte
Você pode fazer em -...\#vez de h:..."\d+"1. Além disso, não há necessidade de converter zem uma lista de caracteres, .>funciona também em uma string.
Jakube 25/02
@Jakube Obrigado pela dica, estava muito cansado quando eu fiz isso. ^^
Denker
1

JavaScript (ES6) 66

Pela primeira vez, o estúpido negativo %de javascript para números negativos se torna útil

z=>(z+z).substr(-(l=z.length,[a,b]=z.match(/\d+/g),b?b+a:a)%l-l,l)
edc65
fonte
1
@WashingtonGuedes não, a soma b+aé uma concatenação de strings. a='32',b='1', (b?b+a:a)=='132', (b|0+a)==33
Edc65
1

Pitão, 10 bytes

.>zss_cz\#

Experimente online. Suíte de teste.

Esta é uma tradução de resposta Cennis Dennis . Estou transformando-o em um wiki da comunidade, pois não o criei.

Explicação

      cz\#   split input at #
     _       reverse
    s        join
   s         cast to integer
.>z          rotate input right
Pietu1998
fonte
1

JavaScript (ES6), 67 64 bytes

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

Outro porto da resposta CJam de Dennis.

Edit: Salva 3 bytes, apropriando-se da parte da resposta do edc65 que ele não chamou a atenção.

Neil
fonte
Usando um ternário e uma soma em vez de reverse () join (), você deve bater a minha pontuação.
edc65
@Downgoat Desculpe, eu tenho acertado com eles ultimamente, mas eu fiz isso tarde da noite e por isso não estava pensando direito.
Neil
@ edc65 Não, isso aumentou minha pontuação. Então, eu copiei o s+struque. (Na verdade, eu pensei sobre isso ontem à noite, mas eu estava muito cansado para testá-lo no momento.)
Neil
1

Perl 5, 41 bytes

39 bytes mais dois para os -lFsinalizadores ( -M5.01é grátis):perl -lF -M5.01 script.pl

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

Explicação:

  • -lFlê a entrada, remove a nova linha à direita, coloca o restante na sequência $_, divide-a em caracteres e coloca essa divisão na matriz @F.
  • /#+/encontra a primeira string de #s in $_e define $`igual ao material anterior e $'igual ao material posterior. Se $`estiver vazio, $'pode conter mais# s. No entanto, $'.$`é uma string cuja substring inicial é o número de vezes para girar a matriz.
  • Agora criamos a lista 1..$'.$` , que trata $'.$`como um número inteiro e, assim, a numera, que retira qualquer #s final ; portanto, a lista é do 1número de vezes que gira o array.
  • Para cada elemento nessa lista, rotacionamos a matriz (pop o último elemento eunshift o início).
  • Então say todos os elementos da matriz rotacionada.
msh210
fonte
1

Rubi - 68 72 70 bytes

s=ARGV[0]
p s.split(//).rotate(-(s+s).scan(/\d+/).map(&:to_i).max)*""
  • split converte string em uma matriz
  • (s+s).scan(/\d+/) concatene a string para si mesma e obtenha uma matriz de números (como strings)
  • map(&:to_i) converter cadeias de caracteres em ints
  • max escolha o maior int
  • rotate max vezes
  • *""converter a matriz novamente em uma string (abreviação de join)

Uso: ruby scriptname.rb "[string]"

FuzzyTree
fonte
Eu sou novo aqui. qual é a etiqueta para postar várias respostas em diferentes idiomas? Eu adicionei uma resposta separada, caso alguém estivesse errado. se não estiver
correto
1
Várias respostas em diferentes idiomas são boas, até incentivadas (desde que todas estejam corretas).
Zgarb
0

05AB1E , 14 13 bytes

Bem, é improvável que o código termine para números maiores que 100000, mas se você for paciente o suficiente, haverá uma saída :). Código:

'#¡rJ¹sF¤rS\J

Explicação:

'#¡             # 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

Experimente online!

Usa a codificação CP-1252

Adnan
fonte
0

VBSCRIPT, 82 99 BYTES

o código anterior não lidava com casos com número agrupado no final

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

isso meio que é péssimo ... provavelmente existe uma maneira melhor de fazê-lo, mesmo em VBscript

Traceur
fonte
Bem-vindo à Programação de quebra-cabeças e troca de pilha de código de golfe. Esta resposta pode ser melhorada adicionando uma explicação e uma explicação do código abaixo do seu código de golfe. Além disso, você pode salvar bytes criando uma função em vez de um programa, onde aestá a entrada da função e ela retorna a saída? Dessa forma, você não precisaria das chamadas inputboxe msgbox.
Wizzwizz4
Por que você precisa b?
CalculatorFeline
0

Mathematica, 73 58 bytes

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

Muito byte. 15 bytes economizados graças ao IPoiler

CalculatorFeline
fonte
StringRotateRightsalva alguns bytes aqui.
IPoiler
0

Matlab (73)

  @(a)regexprep(a,'(\d*)#*(\d*)#*','${circshift($0,[0 str2num([$2 $1])])}')
  • Isso está usando outra abordagem que eu me pergunto se o @luis a usou, porque, referindo-se à sua descrição, existem alguns pontos em comum enquanto (un)? Felizmente eu não entendo a linguagem Matl cortada.
Abr001am
fonte
0

matlab (86) 72

 @(n)circshift(n,[0 str2num(circshift(n(n~='#'),[0,-find(n=='#',1)+1]))])
  • A função gira a string duas vezes, uma vez para extração de número inteiro, a segunda para a tarefa desejada, não leva muito tempo porque o matlab passa a girar (Dim)modulus(Length) exceto que cai na falha de segmentação para intervalos maiores.

  • Vai lutar como jogar mais ....


(86)

  @(n)circshift(n,[0 str2num([strtok(n(find(n=='#',1,'last'):end),'#') strtok(n,'#')])])
  • A diferença entre esta função e a anterior, esta concatena duas ocorrências distantes de números inteiros, ao contrário, enquanto a primeira apenas a gira.
Abr001am
fonte