¿Qué canción está sonando?

33

Inspirado en este xkcd

ingrese la descripción de la imagen aquí

Trabajas para Shazam y ellos tienen un proyecto para ti. Algunos clientes se quejan de que su aplicación ocupa demasiado espacio en su teléfono, por lo que quieren que codifique una versión lite de la aplicación. Desafortunadamente, su código existente solo puede entender la palabra "na", y debe enviarlo pronto. Está bien, haremos lo mejor con lo que tenemos.

El reto

Debe escribir un programa completo que tome una entrada del usuario, o tome un argumento de línea de comando, e imprima el título y el artista de la canción. Como estamos tratando de arreglar a los clientes que se quejan del tamaño del programa, su código debe ser lo más breve posible. La entrada será una cadena que consiste completamente en na, con un solo espacio entre ellas. Minúsculas / mayúsculas es arbitrario. Esto se considera una entrada válida: Na Na nA na NAesta es una entrada no válida: nah nah NA naNa bananadebe determinar qué canción se está reproduciendo e imprimirla exactamente en este formato:

Song: <trackname>
Artist: <artist>

Si la entrada es exactamente 8 na, esto coincide con dos canciones separadas, por lo que debe imprimir ambas:

Song: Batman Theme
Artist: Neal Hefti

y

Song: Na Na Hey Hey Kiss Him Goodbye
Artist: Steam

Si la entrada es exactamente 10 na, debe imprimir:

Song: Katamari Damacy
Artist: Yuu Miyake

Si la entrada es exactamente de 11 na, debe imprimir:

Song: Hey Jude
Artist: The Beatles

Si la entrada es de 12 o más na, debe imprimir

Song: Land Of 1000 Dances
Artist: Wilson Pickett

Por último, si la entrada no es válida, hay menos de 8 na, o alguna de las palabras no es "na", su programa no puede entender la música. Entonces, lógicamente, solo hay otra canción que podría ser. Debes imprimir:

Song: Africa
Artist: Toto

Como de costumbre, se aplican las lagunas estándar y gana la respuesta más corta en bytes.

DJMcMayhem
fuente
2
gran historia de fondo!
TanMath
¿No es Hey Jude 12 nas? Simplemente lo escuché y pensé que era (en términos de duración de las notas) quarter quarter quarter quarter / eighth sixteenth sixteenth quarter-quarter-quarter / eighth sixteenth quarter-quarter-quarter, que es de 12 nas.
Arcturus
44
@Ampora onnnnnnnnne-one-three-one-a-two-threeeeeeeeeee-one-a-two-threeeeeeee-hey-judedefinitivamente 11
quintopia
1
Batman es na na / na na / na na / na nax2 batman. Me di cuenta de que la segunda vez que vi el cómic.
wizzwizz4
2
Son 3 años demasiado tarde para cambiar el desafío, pero debo objetar que el tema Katamari Damacy se titula "Katamari on the Rocks" (o si eres un purista, es oficialmente "Katamari on the Rocks ~ Main Theme") y así ¡no debería aparecer solo como "Katamari Damacy"!
Value Ink

Respuestas:

7

Retina , 242

Pruébalo en línea!

iG`^na( na)*$
iM`na
m`^8$
>Batman Theme,Neal Hefti$n>Na Na Hey Hey Kiss Him Goodbye,Steam
m`^10$
>Katamari Damacy,Yuu Miyake
m`^11$
>Hey Jude,The Beatles
[0-9].+
>Land Of 1000 Dances,Wilson Pickett
m`^[0-9]
>Africa,Toto
>
Song: 
,
$nArtist: 

Cómo funciona:

IgnoreCase flag + Grep mode flag + Regex ^na( na)*$. Si la entrada es válida, imprímala como está. Si no, no imprima nada.

iG`^na( na)*$

IgnoreCase flag + Match mode flag + Regex na. Cuente las "na" e imprima el número.

iM`na

Si la cadena es exactamente "8", reemplácela por la segunda línea.

m`^8$
>Batman Theme,Neal Hefti$n>Na Na Hey Hey Kiss Him Goodbye,Steam

Si la cadena es exactamente "10", reemplácela por la segunda línea.

m`^10$
>Katamari Damacy,Yuu Miyake

Si la cadena es exactamente "11", reemplácela por la segunda línea.

m`^11$
>Hey Jude,The Beatles

Si la cadena coincide [0-9].+, reemplácela por la segunda línea. Esto no es cierto para los números de un solo dígito, 10y 11como ya se han reparado ni ninguna de las cadenas de reemplazo anteriores.

[0-9].+
>Land Of 1000 Dances,Wilson Pickett

Si ninguno de los anteriores coincide, la cadena aún comienza con un número. Por defecto a Toto, África.

m`^[0-9]
>Africa,Toto

Reemplace los marcadores de posición >y ,por Song:y Artist:.

>
Song: 
,
$nArtist: 
Rainer P.
fuente
5

JavaScript (ES6), 276 bytes

alert(`Song: `+([,`Batman Theme,Neal Hefti
Song: Na Na Hey Hey Kiss Him Goodbye,Steam`,,`Katamari Damacy,Yuu Miyake`,`Hey Jude,The Beatles`,`Land Of 1000 Dances,Wilson Pickett`][+prompt(i=0).replace(/na( |$)/gi,_=>++i)&&(i>11?4:i-7)]||`Africa,Toto`).replace(/,/g,`
Artist: `))

Explicación

La entrada puede contener opcionalmente un espacio final.

alert(                 // output the result
  `Song: `+([          // insert the "Song:" label
      ,                // set the first element to undefined in case input is empty

      // Songs
      `Batman Theme,Neal Hefti
Song: Na Na Hey Hey Kiss Him Goodbye,Steam`,
      ,
      `Katamari Damacy,Yuu Miyake`,
      `Hey Jude,The Beatles`,
      `Land Of 1000 Dances,Wilson Pickett`

    ][
      +                // if the input string was made up only of "na"s, the replace would
                       //     return a string containing only digits, making this return a
                       //     number (true), but if not, this would return NaN (false)
        prompt(        // get the input string
          i=0          // i = number of "na"s in input string
        ).replace(     // replace each "na" with a number
          /na( |$)/gi, // find each "na"
          _=>++i       // keep count of the "na"s and replace with a (non-zero) number
        )
      &&(i>11?4:i-7)   // select the song based on the number of "na"s
    ]
      ||`Africa,Toto`  // default to Africa
  ).replace(/,/g,`
Artist: `)             // insert the "Artist:" label
)

Prueba

usuario81655
fuente
Esto no funciona para 9 na's, emite kamari.
Rɪᴋᴇʀ
@RikerW Fijo. Se me olvidó una coma ...
user81655
4

PowerShell, 278 bytes

  • Puede manejar cualquier cantidad de espacio en blanco
  • ¡No hay expresiones regulares!
  • Tipografía implícita FTW!
@{8='Batman Theme/Neal Hefti','Na Na Hey Hey Kiss Him Goodbye/Steam'
10='Katamari Damacy/Yuu Miyake'
11='Hey Jude/The Beatles'
12='Land Of 1000 Dances/Wilson Pickett'}[[math]::Min($args.Count*!($args|?{$_-ne'na'}),12)]|%{'Song: {0}
Artist: {1}'-f($_+'Africa/Toto'*!$_-split'/')}

Sin golf

@{8='Batman Theme/Neal Hefti','Na Na Hey Hey Kiss Him Goodbye/Steam' # array
10='Katamari Damacy/Yuu Miyake'
11='Hey Jude/The Beatles'
12='Land Of 1000 Dances/Wilson Pickett'} # Hashtable of songs
[   # Get value by key from hashtable
    # If key is invalid, silently return null value

    [math]::Min( # Clamp max value to 12
        $args.Count* # Multiply count of argumens
                     # true/false will be cast to 1/0
            ! # Negate result of expression
              # Will cast empty array to 'false'
              # and non-empty array to 'true'
            (
                # Return non-empty array if input arguments
                # contain anything other than 'na'
                $args | Where-Object {$_ -ne 'na'} 
            ),
        12
    )
] | ForEach-Object { # Send value from hashtable down the pipeline,
                     # This allows to process arrays in hasthable values
    'Song: {0}
    Artist: {1}' -f ( # Format string
        $_+ # Add to current pipeline variable
            'Africa/Toto'*!$_ # If pipeline variable is empty,
                              # then add default song to it
                              # Example: 'Test'*1 = 'Test'
                              #          'Test'*0 = null
        -split '/' # Split string to array for Format operator
    )
}

Uso

PS > .\WhatSong.ps1 na na na na na na na na
Song: Batman Theme
Artist: Neal Hefti
Song: Na Na Hey Hey Kiss Him Goodbye
Artist: Steam

PS > .\WhatSong.ps1 Na na na na na na na na na Na
Song: Katamari Damacy
Artist: Yuu Miyake

PS > .\WhatSong.ps1 Na na na na na na na na na BanaNa
Song: Africa
Artist: Toto
beatcracker
fuente
1

sh + coreutils, 290

Aunque es más largo que mi otro envío, este es sencillo y casi no tiene nada de golf, así que lo incluí de todos modos.

grep -Ei "^na( na)*$"|wc -w|awk '{s="Song: ";a="\nArtist: ";p=s"Africa"a"Toto"}$1==8{p=s"Batman Theme"a"Neal Hefti\n"s"Na Na Hey Hey Kiss Him Goodbye"a"Steam"}$1>9{p=s"Katamari Damacy"a"Yuu Miyake"}$1>10{p=s"Hey Jude"a"The Beatles"}$1>11{p=s"Land Of 1000 Dances"a"Wilson Pickett"}{print p}'

Cómo funciona:

Si la entrada es válida, imprímala como está. Si no, no imprima nada.

grep -Ei "^na( na)*$"

Cuenta las palabras.

wc -w

Tabla de búsqueda simple, Song:y Artist:se mantienen en variables.

awk '
    {s="Song: ";a="\nArtist: ";p=s"Africa"a"Toto"}
    $1==8{p=s"Batman Theme"a"Neal Hefti\n"s"Na Na Hey Hey Kiss Him Goodbye"a"Steam"}
    $1>9{p=s"Katamari Damacy"a"Yuu Miyake"}
    $1>10{p=s"Hey Jude"a"The Beatles"}
    $1>11{p=s"Land Of 1000 Dances"a"Wilson Pickett"}
    {print p}
'
Rainer P.
fuente
Sé que ha pasado un tiempo, pero la expresión regular se puede acortar ^(na ?)+$.
Kevin Cruijssen
1

Python 453 440 406 380 bytes

EDITAR: ¡ Gracias a Cyoce por reducir 13 bytes!

EDITAR: Gracias de nuevo a Cyoce!

EDITAR: Gracias a RainerP. por ayudarme a mejorar el algoritmo en ciertos casos no válidos.

Este es un borrador de un programa de Python. Creo que definitivamente se puede jugar golf, quizás a 300-400 bytes. Pero trabajaré en eso pronto.

f=0
S='Song:'
A='\nArtist:'
l="Batman Theme,Neal Hefti,Na Na Hey Kiss Him Goodbye,Steam,Katamari Damacy,Yuu Miyake,Hey Jude,Beatles,Land of the 1000 Dances,Wilson Pickett,Africa,Toto".split(',')
s=raw_input().lower()+" "
n=s.count("na ")
n*=n*3==len(s)
if n>11:f=8
if n==10:f=4
if n==11:f=6
if n<8or n==9:f=10
if f:print S+l[f]+A+l[f+1]
else:print S+l[0]+A+l[1]+"\n"+S+l[2]+A+l[3]

¡Intenta aquí!

TanMath
fuente
En lugar de esa larga lista, use"Batman Theme,Neal Hefti,Na Na Hey Kiss Him Goodbye,Steam,Katamari Damacy,Yuu Miyake,Hey Jude,Beatles,Land of the 1000 Dances,Wilson Pickett,Africa,Toto".split(',')
Cyoce
Además: en lugar de if i not in ["n","a"," "]: ...creo que puedes usar if i not in 'na ': .... Además, if f==0: somecode; else: somemorecodese puede reducir a if f: somemorecode; else: somecode(0 es Falsy)
Cyoce
Aún más (debería haber puesto todo esto en uno, oh bueno): tienes "\nArtist:"tres veces. intente establecer una variable, por ejemplo A="\nArtist:", luego use Aen lugar del literal de cadena. Lo mismo se puede hacer con "Song:". Además, creo que if n<8or n==9:f=10se puede mover a la parte superior de las declaraciones if y cambiar aif n!=8:f=10
Cyoce
Su programa no puede detectar entradas no válidas. La salida es en Batman Themelugar de Africapara na na na nan na na na na.
Rainer P.
@RainerP. Gracias ... Sabía que me faltaba algo ... Ahora estoy trabajando en un algoritmo actualizado
TanMath
1

Julia, 325 bytes

Probablemente podría jugar más golf.

p(s,a)=println("Song: $s\nArtist: $a");ismatch(r"^(na )*na$",ARGS[1])&&(c=length(split(ARGS[1],"na"))-1)==8?(p("Batman Theme","Neal Hefti"),p("Na Na Hey Hey Kiss Him Goodbye","Steam")):c==10?p("Katamari Damacy","Yuu Miyake"):c==11?p("Hey Jude","The Beatles"):c>=12?p("Land Of 1000 Dances","Wilson Pickett"):p("Africa","Toto")
nyuszika7h
fuente
Sé que ha pasado un tiempo, pero la expresión regular se puede acortar ^(na ?)+$.
Kevin Cruijssen
Además, los controles pueden acortarse un poco mediante el uso de <y >en lugar de ==: &&(c=length(split(ARGS[1],"na"))-1)<9?(p("Batman Theme","Neal Hefti"),p("Na Na Hey Hey Kiss Him Goodbye","Steam"))c>11?p("Land Of 1000 Dances","Wilson Pickett"):c>10?p("Hey Jude","The Beatles"):c>9?p("Katamari Damacy","Yuu Miyake"):p("Africa","Toto"). Fuera de tema: me gusta tu avatar. Terminé de ver SAO la semana pasada. ;)
Kevin Cruijssen
1

Moho, 501 477 bytes

fn main(){let(mut i,mut n)=(String::new(),0);let(s,a);std::io::stdin().read_line(&mut i);i=i.trim().to_lowercase();let o=i.split(" ");for w in o{if w!="na"{n=0;break}else{n+=1}}match n{8=>{println!("Song: Batman Theme\nArtist: Neal Hefti");s="Na Na Hey Hey Kiss Him Goodbye";a="Steam"}10=>{s="Katamari Damacy";a="Yuu Miyake"}11=>{s="Hey Jude";a="The Beatles"}_=>{if n>=12{s="Land Of 1000 Dances";a="Wilson Pickett"}else{s="Africa";a="Toto"}}}print!("Song: {}\nArtist: {}",s,a)}

Sin golf

fn main() {
    let (mut input_string, mut na_counter) = (String::new(), 0);
    let (song_name, artist_name);

    std::io::stdin().read_line(&mut input_string);
    input_string = input_string.trim().to_lowercase();
    let output = input_string.split(" ");

    for word in output {
        if word != "na" {
            na_counter = 0;
            break;
        } else {
            na_counter += 1;
        }
    }

    match na_counter {
        8 => {
            println!("Song: Batman Theme\nArtist: Neal Hefti");
            song_name = "Na Na Hey Hey Kiss Him Goodbye";
            artist_name = "Steam";
        }
        10 => {
            song_name = "Katamari Damacy";
            artist_name = "Yuu Miyake";
        }
        11 => {
            song_name = "Hey Jude";
            artist_name = "The Beatles";
        }
        _ => {
            if na_counter >= 12 {
                song_name = "Land Of 1000 Dances";
                artist_name = "Wilson Pickett";
            } else {
                song_name = "Africa";
                artist_name = "Toto";
            }
        }
    }

    print!("Song: {}\nArtist: {}", song_name, artist_name);
}

Editar: eliminó un to_string innecesario y escriba anotaciones

dragonita44
fuente
1

Perl 5 -pa , 248 bytes

$_=/^(na ?)+$/&&(@F==8?",Batman Theme;Neal Hefti,Na Na Hey Hey Kiss Him Goodbye;Steam":@F==10?"Katamari Damacy;Yuu Miyake":@F==11?",Hey Jude;The Beatles":@F>11?",Land Of 1000 Dances;Wilson Pickett":0)||",Africa;Toto";s/;/
Artist: /gm;s/,/
Song: /gm

Pruébalo en línea!

Xcali
fuente
1

Perl 5 , 312 292 bytes

$_=lc<>;$n="(na ?)";/^(na ){7}na$|(na ){9,}na/ or$_="%Africa&Toto";s/$n{12,}/%Land Of 1000 Dances&Wilson Pickett/;s/$n{11}/%Hey Jude&The Beatles/;s/$n{10}/%Katamari Damacy&Yuu Miyake/;s/$n{8}/%Batman Theme&Neal Hefti\n%Na Na Hey Hey Kiss Him Goodbye&Steam/;s/&/\nArtist: /g;s/%/Song: /g;print

Pruébalo en línea!

Sin golf:

$_ = lc <STDIN>;
$_ =~ /^(na ){7}na$|(na ){9,}na/ or $_ = "%Africa&Toto";
$_ =~ s/(na ?){12,}/%Land Of 1000 Dances&Wilson Pickett/;
$_ =~ s/(na ?){11}/%Hey Jude&The Beatles/;
$_ =~ s/(na ?){10}/%Katamari Damacy&Yuu Miyake/;
$_ =~ s/(na ?){8}/%Batman Theme&Neal Hefti\n%Na Na Hey Hey Kiss Him Goodbye&Steam/;
$_ =~ s/&/\nArtist: /g;
$_ =~ s/%/Song: /g;
print $_
pslessard
fuente
Me perdí algunos casos, trabajando en una solución ahora
pslessard
1

C (gcc) , 403 395 370 365 bytes

-8-5 bytes gracias a ceilingcat

Casi tan directo como puede ser.

f(char*s){int*a[]={"Neal Hefti","Steam","Yuu Miyake","The Beatles","Wilson Pickett","Toto","Batman Theme","Na Na Hey Hey Kiss Him Goodbye","Katamari Damacy","Hey Jude","Land Of 1000 Dances","Africa"},i=1,l=0,j=1;for(;*s;s+=s[2]?3:2)i=(*s|32)^'n'|(s[1]|32)^97|s[2]>32,l++;for(i=i?5:l^8?l^10?l^11?l>11?4:5:3:2:j++;j--;)printf("Song: %s\nArtist: %s\n",a[6+i--],a[i]);}

Pruébalo en línea!

gastropner
fuente
0

Java 8, 353 bytes

s->{int n=s.split(" ").length,b=s.matches("(na ?)+")?1:0;s="Africa";return"Song: "+(b>0?n<8?s:n<9?"Batman Theme\nArtist: Neal Hefti\nSong: Na Na Hey Hey Kiss Him Goodbye":n>11?"Land of 1000 Dances":n>10?"Hey Jude":n>9?"Katamari Damacy":"":s)+"\nArtist: "+(b>0?n<8?"Toto":n<9?"Steam":n>11?"Wilson Pickett":n>10?"The Beatles":n>9?"Yuu Miyake":"":"Toto");}

Explicación:

Pruébalo en línea.

s->{                             // Method with String as both parameter and return-type
  int n=s.split(" ").length,     //  The amount of words when split by spaces
      b=s.matches("(na ?)+")?1:0;//  Whether the input matches the regex "^(na ?)+$"
  s="Africa";                    //  Set the input we no longer need to "Africa"
  return"Song: "                 //  Return "Song: "
    +(b>0?                       //   +If the input matched the regex:
       n<8?                      //     If there are less than 8 "na"'s: 
        s                        //      Append "Africa"
       :n<9?                     //     Else-if there are exactly 8 "na"'s:
        "Batman Theme\nArtist: Neal Hefti\nSong: Na Na Hey Hey Kiss Him Goodbye"
                                 //      Append the String above
       :n>11?                    //     Else-if there are 12 or more "na"'s:
        "Land of 1000 Dances"    //      Append "Land of 1000 Dances"
       :n>10?                    //     Else-if there are exactly 11 "na"'s:
        "Hey Jude"               //      Append "Hey Jude"
       :n>9?                     //     Else-if there are exactly 10 "na"'s:
        "Katamari Damacy"        //      Append "Katamari Damacy"
       :                         //     Else (there are exactly 9 "na"'s):
        ""                       //      Append nothing
      :                          //    Else:
       s)                        //     Append "Africa"
    +"\nArtist: "                //   +Append a new-line and "Artist: "
    +(b>0?                       //   +If the input matched the regex:
       n<8?                      //     If there are less than 8 "na"'s:
        "Toto"                   //      Append "Toto"
       :n<9?                     //     Else-if there are exactly 8 "na"'s:
        "Steam"                  //      Append "Steam"
       :n>11?                    //     Else-if there are 12 or more "na"'s:
        "Wilson Pickett"         //      Append "Wilson Pickett"
       :n>10?                    //     Else-if there are exactly 11 "na"'s:
        "The Beatles"            //      Append "The Beatles"
       :n>9?                     //     Else-if there are exactly 10 "na"'s:
        "Yuu Miyake"             //      Append "Yuu Miyake"
       :                         //     Else (there are exactly 9 "na"'s):
        ""                       //      Append nothing
      :                          //    Else:
       "Toto");}                 //     Append "Toto"
Kevin Cruijssen
fuente