¡Hacia arriba y hacia adelante para mayor gloria!

15

Que este desafío sirva como ( otro ) homenaje a Stan Lee, quien falleció a los 95 años.

Stan Lee nos ha dejado un legado invaluable y una palabra peculiar: Excelsior . Así que aquí hay un pequeño desafío basado en lo que dijo que era su significado :

Finalmente, ¿qué significa "Excelsior"? "¡Hacia arriba y hacia adelante para mayor gloria!" ¡Eso es lo que te deseo cada vez que termino de twittear! ¡Virutas de embalaje!

Desafío

Dada una serie de enteros no negativos, genera una línea Excelsior!cada vez que un entero es mayor que el anterior.

Reglas

  • La entrada será una matriz de enteros no negativos.
  • La salida consistirá en líneas con la palabra Excelsior(el caso sí importa) seguido por !la longitud de la ejecución actual de números cada vez mayores. También puede devolver una serie de cadenas.
  • Los formatos de entrada y salida son flexibles de acuerdo con las reglas del sitio, así que siéntase libre de adaptarlos a sus formatos de idioma. También puede agregar espacios al final de las líneas, o incluso nuevas líneas adicionales después o antes del texto si es necesario.

Ejemplos

Input             Output
-----------------------------------
[3,2,1,0,5]       Excelsior!      // Excelsior because 5 > 0

[1,2,3,4,5]       Excelsior!      // Excelsior because 2 > 1
                  Excelsior!!     // Excelsior because 3 > 2 (run length: 2)
                  Excelsior!!!    // Excelsior because 4 > 3 (run length: 3)
                  Excelsior!!!!   // Excelsior because 5 > 4 (run length: 4)

[]                <Nothing>

[42]              <Nothing>

[1,2,1,3,4,1,5]   Excelsior!      // Excelsior because 2 > 1
                  Excelsior!      // Excelsior because 3 > 1
                  Excelsior!!     // Excelsior because 4 > 3 (run length: 2)
                  Excelsior!      // Excelsior because 5 > 1

[3,3,3,3,4,3]     Excelsior!      // Excelsior because 4 > 3

Este es el , ¡así que puede ganar el código más corto para cada idioma!

Charlie
fuente
ouflak asume que los enteros tienen 1 dígito de longitud, ¿está bien
Solo para ASCII el
1
@ ASCII-solo no realmente. No sé si LUA tiene una limitación con eso, pero si ese no es el caso, ouflak debería analizar enteros de cualquier longitud.
Charlie
@Charlie No conozco a Lua, pero aunque es detallado, es posible tomar, por ejemplo, una entrada delimitada por espacios y dividirla así .
Kevin Cruijssen
Lo estoy mirando El truco es poder manejar ambos escenarios.
ouflak
Los lenguajes FWIW como C o Javascript solo manejarán enteros dentro de su precisión (9/16 dígitos) de todos modos.
usuario202729

Respuestas:

9

JavaScript (ES6), 58 54 bytes

a=>a.map(c=>a<(a=c)?`Excelsior${s+='!'}
`:s='').join``

Pruébalo en línea!

Comentado

a =>                           // a[] = input array, also used to store the previous value
  a.map(c =>                   // for each value c in a[]:
    a <                        //   compare the previous value
    (a = c)                    //   with the current one; update a to c
                               //   this test is always falsy on the 1st iteration
    ?                          //   if a is less than c:
      `Excelsior${s += '!'}\n` //     add a '!' to s and yield 'Excelsior' + s + linefeed
    :                          //   else:
      s = ''                   //     reset s to an empty string and yield an empty string
  ).join``                     // end of map(); join everything

¿Por qué es seguro volver a usar un [] para almacenar el valor anterior?

Hay tres casos posibles:

  • Si a[ ] está vacío, la función de devolución de llamada de .map()no se invoca en absoluto y solo obtenemos una matriz vacía, produciendo una cadena vacía.
  • Si a[ ] contiene exactamente un elemento x , se coacciona a ese elemento durante la primera (y única) prueba a < (a = c). Entonces, estamos probando x<x , lo cual es falso. Obtenemos una matriz que contiene una cadena vacía, produciendo nuevamente una cadena vacía.
  • Si a[ ] contiene varios elementos, se coacciona NaNdurante la primera prueba a < (a = c). Por lo tanto, el resultado es falso y lo que se ejecuta es la inicialización de s en una cadena vacía, que es lo que queremos. La primera comparación significativa ocurre en la segunda iteración.
Arnauld
fuente
5

05AB1E , 26 24 23 bytes

ü‹γvyOE.•1Š¥èò²•™N'!׫,

-2 bytes gracias a @Kroppeb .

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

ü                        # Loop over the (implicit) input as pairs
                        #  And check for each pair [a,b] if a<b is truthy
                         #   i.e. [1,2,1,3,4,1,5,7,20,25,3,17]
                         #   → [1,0,1,1,0,1,1,1,1,0,1]
  γ                      # Split it into chunks of equal elements
                         #  i.e. [1,0,1,1,0,1,1,1,1,0,1]
                         #   → [[1],[0],[1,1],[0],[1,1,1,1],[0],[1]]
   vy                    # Foreach `y` over them
     O                   #  Take the sum of that inner list
                         #   i.e. [1,1,1,1] → 4
                         #   i.e. [0] → 0
      E                  #  Inner loop `N` in the range [1, length]:
       .•1Š¥èò²•         #   Push string "excelsior"
                        #   Titlecase it: "Excelsior"
                 N'!׫  '#   Append `N` amount of "!"
                         #    i.e. N=3 → "Excelsior!!!"
                      ,  #   Output with a trailing newline

Ver este consejo 05AB1E mío (sección Cómo comprimir cadenas que no forman parte del diccionario? ) Para entender por qué .•1Š¥èò²•es "excelsior".

Kevin Cruijssen
fuente
2
No se sabe muy bien 05AB1E pero no puedo cambiar el 0Kgcon O?
Kroppeb
@Kroppeb Ah, lo perdí por completo, pero sí, de hecho sí puedo. ¡Gracias! :)
Kevin Cruijssen
5

Perl 6 , 60 58 57 bytes

-1 byte gracias a nwellnhof

{"Excelsior"X~("!"Xx grep +*,[\[&(-+^*×*)]] .skip Z>$_)}

Pruébalo en línea!

Bloque de código anónimo que devuelve una lista de Excelsiors!

Jo King
fuente
4

Java-8 118 113 Bytes

n->{String e="";for(int i=0;i<n.length-1;)System.out.print(""==(n[i+1]>n[i++]?e+="!":(e=""))?e:"Excelsior"+e+"\n");}

Fácil de leer :

private static void lee(int num[]) {
    String exclamation = "";
    for (int i = 0; i < num.length - 1;) {
        exclamation = num[i + 1] > num[i++] ? exclamation += "!" : "";
        System.out.print("".equals(exclamation) ? "" : "Excelsior" + exclamation + "\n");
    }
}
CoderCroc
fuente
2
Aquí hay varios campos de golf para ahorrar el 10 bytes: n->{var e="";for(int i=0;i<n.length-1;System.out.print(""==e?e:"Excelsior"+e+"\n"))e=n[i++]<n[i]?e+="!":"";}. Pruébelo en línea ( 108 bytes ). (Java 10+)
Kevin Cruijssen
@KevinCruijssen ¡Gracias!
CoderCroc
2
n->{for(int e=0,i=0;i<n.length-1;)if(n[i++]<n[i])System.out.println("Excelsior"+"!".repeat(e++));else e=0;}( 107 bytes )
Olivier Grégoire
Solucionando mi problema: en ++elugar de e++que haya al menos uno !para imprimir.
Olivier Grégoire
1
@KevinCruijssen Pequeño error tipográfico en tu golf para hacerte ganar un byte: en e=...?e+"!":lugar de e=...?e+="!":.
Olivier Grégoire
4

R , 86 bytes

La mitad de esta respuesta es de @ Giuseppe. RIP Stan Lee.

function(a)for(i in diff(a))"if"(i>0,cat("Excelsior",rep("!",F<-F+1),"
",sep=""),F<-0)

Pruébalo en línea!

J.Doe
fuente
4

05AB1E , 20 19 bytes

ü‹0¡€ƶ˜ε'!×”¸Îsiorÿ

Pruébalo en línea!

Explicación

ü‹                    # pair-wise comparison, less-than
  0¡                  # split at zeroes
    €ƶ                # lift each, multiplying by its 1-based index
      ˜               # flatten
       ε              # apply to each
        '!×           # repeat "!" that many times
                  ÿ   # and interpolate it at the end of
           ”¸Îsior    # the compressed word "Excel" followed by the string "sior"
Emigna
fuente
4

C (gcc / clang), 106 99 97 bytes

f(a,n)int*a;{int r=0,s[n];for(memset(s,33,n);n-->1;)r*=*a<*++a&&printf("Excelsior%.*s\n",++r,s);}

Gracias a gastropner por jugar al golf 2 bytes.

Pruébalo en línea aquí .

Sin golf:

f(a, n) // function taking a pointer to the first integer and the length of the array
  int *a; { // a is of type pointer to int, n is of type int

    int r = 0, // length of the current run
        i = 0, // loop variable
        s[n];  // buffer for exclamation marks; we will never need more than n-1 of those (we are declaring an array of int, but really we will treat it as an array of char)

    for(memset(s, 33, n); // fill the buffer with n exclamation marks (ASCII code 33)
        n -- > 1; ) // loop over the array

        r *= *a < *(++ a) // if the current element is less than the next:
             && printf("Excelsior%.*s\n", // print (on their own line) "Excelsior", followed by ...
                       ++ r, // ... r (incremented) of the ...
                       s) // ... n exclamation marks in the buffer s
             ; // else r is reset to 0

}
OOBalance
fuente
Comencé a hacer una solución, pero terminé tan cerca de la tuya que publicar la mía como respuesta por separado se sintió un poco tonto. Aún así, las pocas diferencias que existen pueden ahorrarle unos pocos bytes.
Gastropner
@gastropner Gracias por compartir tu versión. He incorporado sus mejoras y lo he ampliado aún más a 99 bytes. Si no tuviéramos que manejar la matriz vacía; de lo contrario, serían 97 bytes , utilizando su estilo de bucle.
OOBalance
4

Japt -R, 25 22 bytes

ò¨ ËÅ£`Ex­lÐâ`ú'!Y+A
c

Intentalo

3 bytes guardados gracias a Kamil

ò¨                      :Partition at items that are greater than or equal to the previous item
   Ë                    :Map
    Å                   :  Slice off the first element
     £                  :  Map each element at 0-based index Y
      `Ex­lÐâ`           :    Compressed string "Excelsior"
             ú'!        :    Right pad with exclamation marks
                Y+A     :     To length Y+10
c                       :Flatten
                        :Implicitly join with newlines & output
Lanudo
fuente
Otros 25 bytes
Luis felipe De jesus Munoz
La -Rbandera no es realmente necesaria, el desafío dice que puede generar una serie de cadenas.
Kamil Drakari
Buena, gracias, @KamilDrakari. Intenté usar una solución sliceen mi primer pase, pero la descarté cuando funcionó demasiado tiempo. Volviendo a eso ahora, con sus indicaciones, supongo que debería haberme quedado con eso porque también lo reduje a 22.
Shaggy
3

Lisp común, 111 bytes

(setq i 0)(loop for(a b)on(read)do(incf i(if(and b(> b a))1(- i)))(format(> i 0)"Excelsior~v@{~a~:*~}~%"i #\!))

Pruébalo en línea!

Renzo
fuente
3

Java 8, 106 bytes

n->{String s="",z=s;for(int i=0;i<n.length-1;)z+=n[i++]<n[i]?"Excelsior"+(s+="!")+"\n":(s="")+s;return z;}

Pruébalo en línea!

(esas reasignaciones de s... yikes)

NotBaal
fuente
Puedes jugar dos bytes más reemplazando (s="")+s=>(s="")
OOBalance
1
n->{String s="",z=s;for(int i=0;i<n.length-1;)z+=n[i++]>=n[i]?s="":"Excelsior"+(s+="!")+"\n";return z;}( 103 bytes ) Mover s=""a bytes de reserva.
Olivier Grégoire
3

R , 111 bytes

function(a,r=rle(sign(diff(a))),v=r$l[r$v>0])write(paste0(rep("Excelsior",sum(v)),strrep("!",sequence(v))),1,1)

Pruébalo en línea!

Aquí se puede encontrar un tributo R mucho mejor : estaba demasiado obsesionado con sequencey rle.

Giuseppe
fuente
¿Esto no da algunas líneas en blanco, sino 86 bytes?
J.Doe
2
@ J.Doe dang, eso es mucho mejor. Lo publicaría yo mismo si fuera tú.
Giuseppe
3

Jalea , 16 bytes

<Ɲṣ0ÄẎ”!ẋ“Ø6ḥ»;Ɱ

Un enlace monádico que produce una lista de listas de caracteres.

Pruébalo en línea!(el pie de página se une con las nuevas líneas)

¿Cómo?

<Ɲṣ0ÄẎ”!ẋ“Ø6ḥ»;Ɱ - Link: list of integers     e.g. [1,1,4,2,1,1,3,4]
 Ɲ               - for each pair of integers:      [1,1] [1,4] [4,2] [2,1] [1,1] [1,3] [3,4]
<                -   less than?                    [  0,    1,    0,    0,    0,    1,    1]
  ṣ0             - split at zeros                  [[],    [1],     [],   [],      [1,    1]]
    Ä            - cumulative sums                 [[],    [1],     [],   [],      [1,    2]]
     Ẏ           - tighten                         [1,1,2]
      ”!         - literal '!' character           '!'
        ẋ        - repeat (vectorises)             [['!'],['!'],['!','!']]
         “Ø6ḥ»   - dictionary lookup               ['E','x','c','e','l','s','i','o','r']
               Ɱ - map with:
              ;  -   concatenate                   [['E','x','c','e','l','s','i','o','r','!'],['E','x','c','e','l','s','i','o','r','!'],['E','x','c','e','l','s','i','o','r','!','!']]
Jonathan Allan
fuente
3

Japt , 22 bytes

ò¨ ®£`Ex­lÐâ`+'!pYÃÅÃc

Pruébalo en línea!

Explicación, con ejemplo simplificado:

ò¨                       :Split whenever the sequence does not increase
                           e.g. [2,1,1,3] -> [[2],[1],[1,3]]
   ®               Ã     :For each sub-array:
    £            Ã       :  For each item in that sub-array:
     `Ex­lÐâ`             :    Compressed "Excelsior"
            +            :    Concat with
             '!pY        :    a number of "!" equal to the index
                               e.g. [1,3] -> ["Excelsior","Excelsior!"]
                  Å      :  Remove the first item of each sub-array
                            e.g. [[Excelsior],[Excelsior],[Excelsior,Excelsior!]]->[[],[],[Excelsior!]]
                    c    :Flatten
                           e.g. [[],[],[Excelsior!]] -> [Excelsior!]
Kamil Drakari
fuente
3

Powershell, 69 bytes

$args|%{if($o-ne$e-and$_-gt$o){'Excelsior'+'!'*++$c}else{$c=0}$o=$_}

Menos guión de prueba de golf:

$f = {

$args|%{
    if($old-ne$empty-and$_-gt$old){
        'Excelsior'+'!'*++$c
    }else{
        $c=0
    }
    $old=$_
}

}

@(
    ,( (3,2,1,0,5),  'Excelsior!')      # Excelsior because 5 > 0

    ,( (1,2,3,4,5),  'Excelsior!',      # Excelsior because 2 > 1
                    'Excelsior!!',     # Excelsior because 3 > 2 (run length: 2)
                    'Excelsior!!!',    # Excelsior because 4 > 3 (run length: 3)
                    'Excelsior!!!!')   # Excelsior because 5 > 4 (run length: 4)

    ,( $null,         '')                # <Nothing>

    ,( (42),          '')                # <Nothing>

    ,( (1,2,1,3,4,1,5), 'Excelsior!',      # Excelsior because 2 > 1
                        'Excelsior!',      # Excelsior because 3 > 1
                        'Excelsior!!',     # Excelsior because 4 > 3 (run length: 2)
                        'Excelsior!')      # Excelsior because 5 > 1

    ,( (3,3,3,3,4,3),   'Excelsior!')      # Excelsior because 4 > 3
) | % {
    $a,$expected = $_
    $result = &$f @a
    "$result"-eq"$expected"
    $result
}

Salida:

True
Excelsior!
True
Excelsior!
Excelsior!!
Excelsior!!!
Excelsior!!!!
True
True
True
Excelsior!
Excelsior!
Excelsior!!
Excelsior!
True
Excelsior!
mazzy
fuente
1
Ahí está, estaba tratando de hacer que funcionara un puntero de retraso pero no podía pensar en cómo.
Veskah
3

PowerShell , 87 85 bytes

param($n)for(;++$i-lt$n.count){if($n[$i]-gt$n[$i-1]){"Excelsior"+"!"*++$c}else{$c=0}}

Pruébalo en línea!

Probablemente hay una reestructuración escondida allí, muy probablemente en el caso contrario, pero en general está bastante bien. Utiliza el viejo truco "La variable no instanciada predeterminada es 0" para hacer tanto el índice como el !.

Veskah
fuente
2

Retina , 55 bytes

\d+
*
L$rv`(_*,(?<!(?(1)\1|\2,)))+(_+)\b
Excelsior$#1*!

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

\d+
*

Convierte a unario.

rv`(_*,(?<!(?(1)\1|\2,)))+(_+)\b

Procesar coincidencias superpuestas de derecha a izquierda (aunque las coincidencias se enumeran de izquierda a derecha). Esto significa que podemos hacer coincidir cada número en una carrera, y la coincidencia se extiende hasta el comienzo de la carrera. Cada coincidencia tiene la restricción adicional de que cada número coincidente adicional debe ser menor que el número adicional coincidente previamente, o el primer número si aún no se han igualado números adicionales.

L$...
Excelsior$#1*!

Para cada coincidencia, imprima Excelsiorcon el número de números adicionales en la ejecución según lo deseado.

Neil
fuente
2

Pyth, 32 bytes

j+L"Excelsior"*L\!fT.u*hN<0Y.+Q0

Pruébelo en línea aquí , o verifique todos los casos de prueba a la vez aquí .

j+L"Excelsior"*L\!fT.u*hN<0Y.+Q0   Implicit: Q=eval(input())
                            .+Q    Get forward difference between consecutive elements of Q
                    .u         0   Reduce the above, returning all steps, with current value N starting at 0, next element as Y, using:
                       hN            N+1
                      *              Multiplied by
                         <0Y         1 if 0<Y, 0 otherwise
                  fT               Filter to remove 0s
              *L\!                 Repeat "!" each element number of times
 +L"Excelsior"                     Prepend "Excelsior" to each
j                                  Join on newlines, implicit print
Sok
fuente
2

Lua , 88 87 83 82 96 95 113 bytes

Gracias @Kevin Cruijssen por actualizarse al espíritu de la pregunta original.

s=io.read()n=9 e="Excelsior!"f=e
for c in s.gmatch(s,"%S+")do if n<c+0then print(e)e=e..'!'else e=f end n=c+0 end

Pruébalo en línea!

ouflak
fuente
1
Lo sentimos, pero debe imprimir el signo de exclamación de acuerdo con las reglas (un signo de exclamación por longitud de la ejecución actual de números cada vez mayores).
Charlie
No hay problema. Creo que he hecho todo lo que puedo hacer aquí a menos que alguien más vea algo ...
ouflak
1
No conozco a Lua demasiado bien, pero aquí hay una solución para su código, por lo que ejecuta todos los casos de prueba correctamente. Actualmente solo imprime un "!" cada vez que un número es más alto que el anterior, pero no lo restablece a 1 cuando ese no es el caso. Probablemente se pueda jugar más al golf, pero como nunca he jugado golf en Lua, me concentré en arreglarlo solo con pequeños campos de golf. PD: No estoy seguro de si suponer que la entrada es siempre de un solo dígito es correcta ..
Kevin Cruijssen
2
Dado que @Charlie mencionó en un comentario debajo de la descripción del desafío que debería ser posible tomar números de varios dígitos como entrada, aquí una posible solución al tomar una entrada delimitada por espacios y dividirla .
Kevin Cruijssen
Decidí que las modificaciones de Kevin Cruijssen están más en línea con las expectativas del OP. ¡Gracias!
ouflak
2

C ++ 14 (g ++), 123 118 bytes

[](auto a){for(int n=0,i=0;++i<a.size();)a[i]>a[i-1]?puts(&("Excelsior"+std::string(++n,33))[0]):n=0;}

Afortunadamente std::stringtiene un constructor que repite a char. Pruébalo en línea aquí .

Gracias a gastropner por guardar 5 bytes.

Sin golf:

[] (auto a) { // void lambda taking a std::array of integer

    for(int n = 0, // length of the current run
        i = 0; // loop variable
        ++ i < a.size(); ) // start with the second element and loop to the last
        a[i] > a[i - 1] // if the current element is greater than the previous ...
        ? puts( // ... print a new line:
               &("Excelsior" + // "Excelsior, followed by ...
                std::string(++ n, 33)) // ... the appropriate number of exclamation marks (33 is ASCII code for '!'); increment the run length
               [0]) // puts() takes a C string
        : n = 0; // else reset run length

}
OOBalance
fuente
Puede recortar otros 5 bytes
gastropner
2

C # (.NET Core) , 115 107 105 bytes

a=>{var b="";for(int i=0;++i<a.Length;)if(a[i]>a[i-1])Console.WriteLine("Excelsior"+(b+="!"));else b="";}

Pruébalo en línea!

-8 bytes: cambiado b a una cadena que contiene "!" S desde un contador int
-2 bytes: establecido b+="!" como una función en línea (gracias a Zac Faragher )

Utiliza un delegado de acción para extraer la entrada y no requiere un retorno.

Sin golf:

a => {
    var b = "";                         // initialize the '!' string (b)
    for(int i = 0; ++i < a.Length;)     // from index 1 until the end of a
        if(a[i] > a[i - 1])                 // if the current index is greater than the previous index
            Console.WriteLine("Excelsior" +     // on a new line, print "Excelsior"
                                    (b += "!"));    // add a "!" to b, and print the string
        else                                // if the current index is not greater than the previous index
            b = "";                             // reset b
}
Suricata
fuente
1
puede ahorrar 2 bytes haciendo la b+="!"línea con el Excelsior ¡ if(a[i]>a[i-1])Console.WriteLine("Excelsior"+(b+="!")); Pruébelo en línea!
Zac Faragher
2

PHP , 117109 bytes

<?php do{$i=next($argv);if($p!==null&&$p<$i){$e.='!';echo "
Excelsior$e";}else$e='';$p=$i;}while($i!==false);

Pruébalo en línea!

Scoots
fuente
2

J, 50 bytes

'Excelsior',"1'!'#"0~[:;@(([:<+/\);._1)0,2</\ ::0]

Pruébalo en línea!

sin golf

'Excelsior' ,"1 '!' #"0~ [: ;@(([: < +/\);._1) 0 , 2 </\ ::0 ]
Jonás
fuente
1

Java, 113 bytes

String i="";for(int a=0;a<s.length-1;a++){if(s[a+1]>s[a]){i+="!";System.out.println("Excelsior"+i);}else{i="";}}
isaace
fuente
1

VBA, 114 bytes

For i=0 To UBound(a)-LBound(a)-1 If a(i+1)>a(i)Then s=s&"!" Debug.Print("Excelsior"&s&"") Else s="" End If Next i
isaace
fuente
Por desgracia, esto no es una solución válida, ya que se basa en tener una variable definida de manera explícita, a. Dicho esto, si define la función como una subroutineque toma la entrada como una variante de la matriz de tipos esperada, puede convertir su enfoque en una solución válida. Se vería una versión de golf de ese enfoque sub f(x) For i=0To UBound(x)-1 If x(i+1)>x(i)Then s=s+"!":Debug.?"Excelsior"s:Else s="" Next End Sub, donde los descansos entre el bloque de código representan nuevas líneas
Taylor Scott,
1

Python 3, 87 bytes

c='!'
for i in range(1,len(n)):
    if n[i]>n[i-1]:print('Excelsior'+c);c+='!'
    else:c='!'

O 97 con lo siguiente:

c='!';n=input()
for i in range(1,len(n)):
    if n[i]>n[i-1]:print('Excelsior'+c);c+='!'
    else:c='!'

Esto supone que las entradas estarán en el formato:

32105
12345
<null input>
1
1213415
333343
Henry T
fuente
1
Su primer programa no es válido ya que recibe información a través de una variable predefinida. El segundo es invalud ya que no puede distinguir entre números con múltiples dígitos. ¿Por qué no usar Python 2 o convertirlo en una función ?
Jo King