Localizar y rotar


30

La tarea

Este es un desafío simple. Su entrada es una sola cadena no vacía, que contiene solo dígitos 0123456789y hashes #. Contendrá exactamente una serie de dígitos, que codifica un entero no negativo y puede ajustarse alrededor del final de la cadena, y al menos uno #. El entero puede tener ceros a la izquierda. Por ejemplo, ##44##, 013####y 23###1son entradas válidas, mientras que ###, 0099y #4#4no lo son.

Su tarea es extraer el número entero nde la cadena y generar los npasos rotados de la cadena a la derecha.

Ejemplos

  • La entrada #1##debe girarse 1 paso hacia la derecha, por lo que la salida correcta es ##1#.
  • La entrada #026###debe girarse 26 pasos hacia la derecha, ya que se ignora el 0 inicial. La salida correcta es 26####0.
  • La entrada 1####2contiene el número entero 21 envuelto sobre el extremo, por lo que debe rotarse 21 pasos hacia la derecha. La salida correcta es ##21##.

Reglas y puntaje

Puede escribir un programa completo o una función. El conteo de bytes más bajo gana, y las lagunas estándar no se permiten.

Puede suponer que el número se najusta al inttipo estándar de su idioma. Por el contrario, si ese inttipo estándar implementa enteros de precisión arbitraria, debe admitir (en teoría) un arbitrariamente grande n.

Casos de prueba

#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

77
¿Tenemos que admitir todos los casos de prueba? Algunos de esos números son bastante grandes ... ¿Sería aceptable usar un lenguaje con enteros de 8 bits?
Dennis

@Dennis Es posible resolver el desafío con la aritmética modular sin cargar realmente el entero en la memoria ... pero tienes razón, es una molestia en muchos idiomas. Digamos que solo necesita manejar esos casos de prueba donde se najusta al inttipo nativo de su idioma (que puede ser de precisión arbitraria). Actualizaré el texto del desafío más tarde.
Zgarb

¿Qué debemos hacer si input = 1234?
CalculadoraFeline

2
@CatsAreFluffy "y al menos un #"
FryAmTheEggman

Respuestas:


10

CJam, 11 bytes

q_'#%W%sim>

Pruébalo en línea! o verificar todos los casos de prueba .

Tenga en cuenta que esto no funcionará en los últimos dos casos de prueba, ya que los números involucrados no caben en 64 bits.

Cómo 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.

Oooh ... tan simple!
Luis Mendo

7

Julia, 71 65 bytes

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

Esta es una función anónima que acepta una cadena y devuelve una cadena. Para llamarlo, asígnelo a una variable.

Agregamos la entrada a sí mismo, la dividimos en una matriz con #el separador, analizamos cada número entero y tomamos el máximo. Esto define el número de veces que desplazamos la cadena a la derecha. Dividimos la cadena en una Charmatriz, la desplazamos y joinla juntamos nuevamente.


7

Python, 66 bytes

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

5

Retina, sesenta y cinco 57 49

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

¡Guardado 8 bytes gracias a Martin!

Pruébalo en línea!

Tenga en cuenta que esto agota el tiempo / se agota la memoria para los casos de prueba muy grandes en línea, y en la mayoría de las máquinas sanas, para algunos de los más grandes.

Esto toma el último número en la cadena y el primer o ningún número en la cadena y los coloca delante de la cadena. Luego convierte ese número combinado en unario y gira repetidamente mientras suelta un dígito unario.


3

Jalea, 12 10 bytes

ẋ2~ṣ0‘ḌṂṙ@

Pruébalo en línea! o verificar todos los casos de prueba .

Fondo

Digamos que la entrada es 51379#97.

Al repetir la cadena dos veces ( 51379#9751379#97), podemos asegurarnos de que contendrá una representación contigua del número.

A continuación, aplicamos NO a nivel de bits a todos los caracteres. Esto intenta convertir a int, por lo que '1' se evalúa a 1 , luego se asigna a ~ 1 = -2 . En caso de fallo ( #), devuelve 0 .

Para nuestro ejemplo, esto da

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

Luego, nos dividimos en ceros para separar la parte que codifica el número del resto.

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

Bitwise NO asigna n a -n - 1 , por lo que incrementamos cada uno para obtener -n .

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

A continuación, convertimos cada lista de base 10 a entero.

[-51379, -9751379, -97]

El número más bajo es el negativo del que estamos buscando. Dado que el átomo de rotación de la lista Jelly gira hacia la izquierda , esto evita multiplicarse por -1 para girar hacia la derecha.

Cómo 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.

3

MATL , 28 25 17 16 bytes

!G1Y4XXPZcXvUYS!

8 bytes menos tomando prestada la idea de Dennis de dividir la matriz e invertir el orden de las piezas

Los dos últimos casos de prueba no funcionan porque el número es demasiado grande.

EDITAR (20 de mayo de 2016) El código en el enlace se usa en Xzlugar de Xv, debido a cambios recientes en el idioma.

Pruébalo en línea!

!         % 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

2

PowerShell, 153 bytes

(Pero consulte la sección Crédito adicional, a continuación)

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 no tiene el concepto de "cambiar" una matriz, por lo que tuve que lanzar mi propia solución. Tomará mucho tiempo para números más grandes, pero eventualmente debería completar todo lo que cabe en un int de 32 bits.

Toma entrada $ay establece una nueva variable $dcomo un objeto [System.Collections.ArrayList] . Esto se hace porque, técnicamente, las matrices en PowerShell son inmutables (se explica más adelante en Crédito adicional) y, por lo tanto, no admiten inserciones o eliminaciones arbitrarias, lo cual es necesario para el cambio. Luego, entramos en un forbucle.

La condición inicial es un truco que encontré: si concatenamos la entrada, la dividimos #e ignoramos los vacíos, el segundo elemento de la matriz resultante será igual a nuestro número, independientemente de la envoltura. Lo configuramos $by disminuimos $bcada vez hasta que sea cero.

En cada iteración, establecemos helper $rcomo el último elemento en la lista de matrices, eliminamos ese último elemento y luego insertamos el elemento en el frente ... efectivamente "desplazando" la matriz a la derecha por un elemento.

Finalmente, simplemente imprimimos con -join$dpara que se concatene en una cadena.


Crédito adicional

Si el problema era desplazar la matriz hacia la izquierda en lugar de hacia la derecha , podemos hacerlo significativamente más corto usando la asignación múltiple . Básicamente, "Si el valor de asignación contiene más elementos que variables, todos los valores restantes se asignan a la última variable".

En esencia, esto significa algo así $c=@(1,2,3)y $a,$b=$c
tendrá $a=1un int y $b=@(2,3)una matriz.

PowerShell, 90 bytes, realiza un desplazamiento a la izquierda en lugar de un desplazamiento a la derecha

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

Aquí tomamos una vez más la entrada y la configuramos $bcomo se indica arriba. Relanzamos $acomo un conjunto de caracteres y luego ingresamos al mismo forbucle que el anterior. Esta vez, sin embargo, no hemos necesitado admitir la eliminación / inserción arbitraria, por lo que no necesitamos usar el [System.Collections.ArrayList]objeto costoso ni las llamadas a métodos costosos. En cambio, simplemente establecemos $rser el primer elemento de $a, y los elementos restantes se vuelven a guardar $a. Luego debemos +=volver a clavarlo hasta el final.

(Como dije, las matrices de PowerShell son técnicamente inmutables, pero el +=operador aquí está sobrecargado: toma una matriz y otro objeto, los agrupa (término técnico) en una nueva matriz, lo devuelve y lo guarda como el nombre de la variable, y destruye la matriz original. Funcionalmente, acabamos de agregar un elemento al final de la matriz, pero técnicamente (y desde una perspectiva de memoria / limpieza de basura, etc.) es una matriz nueva. Esto obviamente puede convertirse en una operación costosa si la matriz es grande o compleja. La otra cara es que, dado que las matrices son inmutables, indexarlas o iterar sobre ellas es muy barato).

La salida sigue siendo la misma acción, con una -joindeclaración para convertirla en una sola cadena.


1

En serio, 21 bytes

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

Pruébalo en línea!

Advertencia: esta solución es muy ineficiente, por lo que los casos de prueba más grandes se agotarán en TIO. Utiliza el intérprete local.

Explicación:

,;;+'#@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

Concat y aprovecha al máximo: ¡gran idea!
Luis Mendo

@LuisMendo Me divirtió ver aparecer la respuesta de Alex con la misma estrategia mientras escribía la explicación aquí.
Mego

Parece que el único que inicialmente usó el enfoque ingenuo fui yo :-) (girando la cadena inicial hasta que todos los dígitos fueran contiguos)
Luis Mendo

1

Mathematica, 69 Bytes

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

Encuentre secuencias de números en el, si hay 2, entonces su orden debe invertirse. Concatene las cadenas (si es solo una, solo devuelve la cadena del número). Convierta la cadena en numérica y gire la cadena esa cantidad de veces.


FromDigitsfunciona en lugar de ToExpression.
CalculatorFeline

1

Pyth, 22 14 bytes

.>zs-.<zxz\#\#

Pruébalo aquí!

Explicación

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

     . <z # gire z hacia la izquierda
        xz \ # # índice de la primera aparición de un hash
                  # esto asegura que el entero no esté envuelto alrededor del final
    - \ # # filtra todos los hashes
   s # emitido a un entero, también elimina los ceros a la izquierda
.> z # realiza la rotación final de la cadena de entrada e imprime

Esto funciona para todos los casos de prueba y también casi termina instantáneamente para los números muy grandes.


Puedes hacer en -...\#lugar de h:..."\d+"1. Además, no es necesario convertirlo zen una lista de caracteres, .>también funciona en una cadena.
Jakube

@Jakube Gracias por la pista, estaba bastante cansado cuando hice esto. ^^
Denker

1

JavaScript (ES6) 66

Por una vez, el estúpido negativo %de javascript para números negativos es útil

z=>(z+z).substr(-(l=z.length,[a,b]=z.match(/\d+/g),b?b+a:a)%l-l,l)

1
@WashingtonGuedes no, la suma b+aes una concatenación de cadenas. a='32',b='1', (b?b+a:a)=='132', (b|0+a)==33
edc65


1

JavaScript (ES6), 67 64 bytes

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

Otro puerto de la respuesta CJam de Dennis.

Editar: ahorró 3 bytes al apropiarse de la parte de la respuesta de edc65 a la que no llamó la atención.


Usando un ternario y una suma en lugar de reverse ().
Join

@Downgoat Lo siento, últimamente lo he hecho bien, pero hice esto a altas horas de la noche y no pensaba bien.
Neil

@ edc65 No, eso hizo que mi puntaje fuera más alto. Así que copié el s+struco en su lugar. (De hecho, pensé en eso anoche, pero estaba demasiado cansado para probarlo en ese momento.)
Neil,

1

Perl 5, 41 bytes

39 bytes más dos para las -lFbanderas ( -M5.01es gratis):perl -lF -M5.01 script.pl

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

Explicación:

  • -lFlee la entrada, elimina la nueva línea final, coloca el resto en la cadena $_, lo divide en caracteres y lo divide en la matriz @F.
  • /#+/encuentra la primera cadena de #s en $_y establece $`igual a las cosas antes e $'igual a las cosas después de ella. Si $`está vacío, $'puede contener más #s. Sin embargo, $'.$`es una cadena cuya subcadena inicial es la cantidad de veces que gira la matriz.
  • Ahora construimos la lista 1..$'.$`, que trata $'.$`como un número entero y, por lo tanto, la numera, lo que elimina cualquier #s final , por lo que la lista es desde 1el número de veces que gira la matriz.
  • Para cada elemento de esa lista, rotamos la matriz ( popel último elemento y unshiftel principio).
  • Entonces saytodos los elementos de la matriz girada.

1

Ruby - 68 72 70 bytes

s=ARGV[0]
p s.split(//).rotate(-(s+s).scan(/\d+/).map(&:to_i).max)*""
  • split convierte la cadena en una matriz
  • (s+s).scan(/\d+/) concatenar cadena a sí mismo y obtener una matriz de números (como cadenas)
  • map(&:to_i) convertir cadenas a ints
  • max elige el int más grande
  • rotate max veces
  • *""convertir la matriz de nuevo en una cadena (abreviatura de join)

Uso: ruby scriptname.rb "[string]"


soy nuevo aqui. ¿Cuál es la etiqueta al publicar múltiples respuestas en diferentes idiomas? Agregué una respuesta separada en caso de que uno estuviera equivocado. si no está bien agregar varias respuestas, avíseme y lo eliminaré
FuzzyTree

1
Las respuestas múltiples en diferentes idiomas están bien, incluso se recomiendan (siempre que sean correctas).
Zgarb

0

05AB1E , 14 13 bytes

Bueno, es muy poco probable que el código termine para los números mayores de 100000, pero si eres lo suficientemente paciente, habrá una salida :). Código:

'#¡rJ¹sF¤rS\J

Explicación:

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

Pruébalo en línea!

Utiliza codificación CP-1252


0

VBSCRIPT, 82 99 BYTES

el código anterior no manejaba casos con número envuelto al 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)

SIN GOLF

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

esto apesta ... probablemente hay una mejor manera de hacerlo, incluso en VBscript


Bienvenido a Programming Puzzles y Code Golf Stack Exchange. Esta respuesta podría mejorarse agregando un desglose de código y una explicación debajo de su código de golf. Además, ¿podría guardar bytes creando una función en lugar de un programa, dónde aestá la entrada de la función y devuelve la salida? De esa manera, no necesitarías las llamadas inputboxy msgbox.
wizzwizz4

¿Por qué lo necesitas b?
CalculatorFeline

0

Mathematica, 73 58 bytes

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

Mucho byte. 15 bytes guardados gracias a IPoiler


StringRotateRightguarda algunos bytes aquí.
IPoiler

0

Matlab (73)

  @(a)regexprep(a,'(\d*)#*(\d*)#*','${circshift($0,[0 str2num([$2 $1])])}')
  • Esto está utilizando otro enfoque que me pregunto si @luis lo usó, porque al referirme a su descripción, hay algunos puntos en común, mientras que (desafortunadamente) no entiendo el lenguaje recortado de Matl.

0

matlab (86) 72

 @(n)circshift(n,[0 str2num(circshift(n(n~='#'),[0,-find(n=='#',1)+1]))])
  • La función gira la cadena dos veces, una vez para la extracción de enteros, la segunda para la tarea deseada, no toma demasiado tiempo porque Matlab continúa girando (Dim)modulus(Length)a excepción de que cae en la falla de segmentación para rangos más grandes.

  • Te costará cómo jugar más al golf ...


(86)

  @(n)circshift(n,[0 str2num([strtok(n(find(n=='#',1,'last'):end),'#') strtok(n,'#')])])
  • La diferencia entre esta función y la anterior, esta concatena dos ocurrencias distantes de enteros hacia atrás, mientras que la primera simplemente la gira.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.