Que música está tocando?


33

Inspirado por este xkcd

insira a descrição da imagem aqui

Você trabalha para o Shazam e eles têm um projeto para você. Alguns clientes estão reclamando que o aplicativo ocupa muito espaço no telefone, então eles querem que você codifique uma versão básica do aplicativo. Infelizmente, seu código existente pode entender apenas a palavra "na" e você deve enviar em breve. Tudo bem, faremos o melhor com o que temos.

O desafio

Você deve escrever um programa completo que receba uma entrada do usuário ou use um argumento de linha de comando e imprima o título e o artista da música. Como estamos tentando corrigir os clientes que reclamam do tamanho do programa, seu código deve ser o mais curto possível. A entrada será uma string que consiste inteiramente de na's, com um único espaço entre eles. Minúsculas / maiúsculas são arbitrárias. Isso é considerado uma entrada válida: Na Na nA na NAEsta é uma entrada inválida: nah nah NA naNa bananavocê deve determinar qual música está tocando e imprimi-la exatamente neste formato:

Song: <trackname>
Artist: <artist>

Se a entrada for exatamente 8 na, corresponde a duas músicas separadas, portanto, você deve imprimir as duas:

Song: Batman Theme
Artist: Neal Hefti

e

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

Se a entrada for exatamente 10 na, você deverá imprimir:

Song: Katamari Damacy
Artist: Yuu Miyake

Se a entrada for exatamente 11 na, você deverá imprimir:

Song: Hey Jude
Artist: The Beatles

Se a entrada for 12 ou mais na's, você deverá imprimir

Song: Land Of 1000 Dances
Artist: Wilson Pickett

Por fim, se a entrada for inválida, há menos de 8 na's ou qualquer uma das palavras não é "na", seu programa não consegue entender a música. Então, logicamente, há apenas uma outra música que poderia ser. Você deve imprimir:

Song: Africa
Artist: Toto

Como de costume, as brechas padrão se aplicam e a resposta mais curta em bytes vence.


2
grande história de fundo!
TanMath

Hey Jude não é 12 nas? Acabei de ouvi-lo e pensei que fosse (em termos de tamanho das notas) quarter quarter quarter quarter / eighth sixteenth sixteenth quarter-quarter-quarter / eighth sixteenth quarter-quarter-quarter, ou seja, 12 nasegundos.
quer

4
@Ampora onnnnnnnnne-one-three-one-a-two-threeeeeeeeeee-one-a-two-threeeeeeee-hey-judedefinitivamente 11
quintopia

1
Batman é na na / na na / na na / na nax2 batman. Percebi que na segunda vez que vi os quadrinhos.
wizzwizz4

2
É 3 anos tarde demais para mudar o desafio, mas devo objetar que o tema Katamari Damacy se intitule "Katamari on the Rocks" (ou, se você é um purista, é oficialmente "Katamari on the Rocks ~ Tema Principal") e, portanto, não deve ser listado apenas como "Katamari Damacy"!
Value Ink

Respostas:


7

Retina , 242

Experimente online!

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: 

Como funciona:

Sinalizador IgnoreCase + sinalizador de modo Grep + Regex ^na( na)*$. Se a entrada for válida, imprima-a como está. Caso contrário, imprima nada.

iG`^na( na)*$

Sinalizador IgnoreCase + Sinalizador de modo de correspondência + Regex na. Conte os "na" se imprima o número.

iM`na

Se a sequência for exatamente "8", substitua pela segunda linha.

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

Se a sequência for exatamente "10", substitua pela segunda linha.

m`^10$
>Katamari Damacy,Yuu Miyake

Se a sequência for exatamente "11", substitua pela segunda linha.

m`^11$
>Hey Jude,The Beatles

Se a sequência corresponder [0-9].+, substitua pela segunda linha. Isso não é verdade para números de um dígito 10e , 11como eles já foram substituídos, nem nenhuma das cadeias de substituição acima.

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

Se nenhuma das opções acima corresponder, a sequência ainda começará com um número. Padrão para Toto, África.

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

Substitua os espaços reservados >e ,por Song:e Artist:.

>
Song: 
,
$nArtist: 

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: `))

Explicação

Opcionalmente, a entrada pode conter um espaço à direita.

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
)

Teste


Isso não funciona para 9 na's, gera kamari.
Rɪᴋᴇʀ

@RikerW Fixed. Eu esqueci uma vírgula ...
user81655

4

PowerShell, 278 bytes

  • Pode lidar com qualquer quantidade de espaço em branco
  • Sem regex!
  • Impressão implícita de 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'/')}

Ungolfed

@{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

1

sh + coreutils, 290

Embora seja mais longo que o meu outro envio, este é direto e praticamente não-destruído, então eu o incluí de qualquer maneira.

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}'

Como funciona:

Se a entrada for válida, imprima-a como está. Caso contrário, imprima nada.

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

Conte as palavras.

wc -w

Tabela de consulta simples Song:e Artist:são mantidas em variáveis.

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}
'

Eu sei que já faz um tempo, mas o regex pode ser reduzido para ^(na ?)+$.
Kevin Cruijssen

1

Python 453 440 406 380 bytes

EDIT: Agradecimentos a Cyoce por reduzir 13 bytes!

EDIT: Mais uma vez obrigado a Cyoce!

EDIT: Obrigado a RainerP. por me ajudar a melhorar o algoritmo em certos casos inválidos.

Este é um rascunho de um programa Python. Eu acredito que pode ser definitivamente jogado, talvez para 300-400 bytes. Mas vai trabalhar nisso em breve.

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]

Tente aqui!


Em vez disso longa 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

Além disso: em vez de if i not in ["n","a"," "]: ...eu acredito que você pode usar if i not in 'na ': .... Além disso, if f==0: somecode; else: somemorecodepode ser reduzido para if f: somemorecode; else: somecode(0 é falso)
Cyoce

Ainda mais (eu deveria ter colocado tudo isso em um, tudo bem): você tem "\nArtist:"três vezes. tente definir uma variável, por exemplo A="\nArtist:", depois use Ano lugar da string literal. O mesmo pode ser feito com "Song:". Além disso, acho que isso if n<8or n==9:f=10pode ser movido para o topo das instruções if e alterado paraif n!=8:f=10
Cyoce

Seu programa falha ao detectar entrada inválida. A saída é em Batman Themevez de Africapara na na na nan na na na na.
Rainer P.

@RainerP. Obrigado ... Eu sabia que estava faltando alguma coisa ... Agora estou trabalhando em um algoritmo atualizados
TanMath

1

Julia, 325 bytes

Provavelmente poderia ser jogado mais.

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")

Eu sei que já faz um tempo, mas o regex pode ser reduzido para ^(na ?)+$.
Kevin Cruijssen

Além disso, os controlos pode ser encurtado um pouco usando <e >, em vez 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"). Fora do tópico: eu gosto do seu avatar. Terminou de assistir o SAO na semana passada. ;)
Kevin Cruijssen

1

Ferrugem, 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)}

Ungolfed

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: removeu uma to_string desnecessária e digite anotações


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

Experimente online!


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

Experimente online!

Ungolfed:

$_ = 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 $_


1

C (GCC) , 403 395 370 365 bytes

-8 -5 bytes graças ao ceilingcat

Praticamente o mais direto possível.

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]);}

Experimente online!


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");}

Explicação:

Experimente online.

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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.