Która piosenka gra?


33

Zainspirowany tym xkcd

wprowadź opis zdjęcia tutaj

Pracujesz dla Shazam, a oni mają dla ciebie projekt. Niektórzy klienci skarżą się, że ich aplikacja zajmuje zbyt dużo miejsca w telefonie, dlatego chcą, abyś napisał wersję lite aplikacji. Niestety Twój istniejący kod może zrozumieć tylko słowo „na” i wkrótce musisz go wysłać. W porządku, zrobimy najlepiej z tym, co mamy.

Wyzwanie

Musisz napisać pełny program, który pobiera dane od użytkownika lub argument wiersza poleceń, i wypisuje tytuł i wykonawcę utworu. Ponieważ próbujemy naprawić klientów narzekających na rozmiar programu, Twój kod musi być możliwie jak najkrótszy. Dane wejściowe będą ciągiem złożonym całkowicie z na, z pojedynczym odstępem między nimi. Małe / wielkie litery są dowolne. Jest to uważane za prawidłowe wejście: Na Na nA na NATo jest nieprawidłowe wejście: nah nah NA naNa bananaMusisz określić, który utwór jest odtwarzany i wydrukować go dokładnie w tym formacie:

Song: <trackname>
Artist: <artist>

Jeśli wejście ma dokładnie 8 na, pasuje to do dwóch oddzielnych utworów, więc musisz wydrukować oba:

Song: Batman Theme
Artist: Neal Hefti

i

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

Jeśli dane wejściowe wynoszą dokładnie 10 na, musisz wydrukować:

Song: Katamari Damacy
Artist: Yuu Miyake

Jeśli dane wejściowe wynoszą dokładnie 11 na, musisz wydrukować:

Song: Hey Jude
Artist: The Beatles

Jeśli dane wejściowe to 12 lub więcej na, musisz wydrukować

Song: Land Of 1000 Dances
Artist: Wilson Pickett

Wreszcie, jeśli dane wejściowe są niepoprawne, jest mniej niż 8 na lub którekolwiek ze słów nie są „na”, twój program nie rozumie muzyki. Logicznie rzecz biorąc, jest tylko jedna piosenka, którą mogłaby być. Musisz wydrukować:

Song: Africa
Artist: Toto

Jak zwykle obowiązują standardowe luki i wygrywa najkrótsza odpowiedź w bajtach.


2
świetna historia w tle!
TanMath,

Czy to nie Hej Jude 12 nas? Właśnie go wysłuchałem i pomyślałem, że to (pod względem długości nut) quarter quarter quarter quarter / eighth sixteenth sixteenth quarter-quarter-quarter / eighth sixteenth quarter-quarter-quarter, czyli 12 nas.
Arcturus

4
@Ampora onnnnnnnnne-one-three-one-a-two-threeeeeeeeeee-one-a-two-threeeeeeee-hey-judezdecydowanie 11
kwintopia

1
Batman to na na / na na / na na / na nax2 batman. Zauważyłem, że drugi raz widziałem komiks.
wizzwizz4

2
Jest 3 lata za późno, by zmienić wyzwanie, ale muszę sprzeciwić się temu, że motyw Katamari Damacy nosi tytuł „Katamari on the Rocks” (lub jeśli jesteś purystą, to oficjalnie „Katamari on the Rocks ~ Main Theme”), a zatem nie powinien być tylko wymieniony jako „Katamari Damacy”!
Wartość tuszu

Odpowiedzi:


7

Retina , 242

Wypróbuj 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: 

Jak to działa:

Flaga IgnoreCase + flaga trybu Grep + Regex ^na( na)*$. Jeśli dane wejściowe są prawidłowe, wydrukuj je bez zmian. Jeśli nie, nie drukuj niczego.

iG`^na( na)*$

Flaga IgnoreCase + flaga trybu dopasowania + Regex na. Policz „na” i wydrukuj numer.

iM`na

Jeśli ciąg ma dokładnie „8”, zastąp go drugim wierszem.

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

Jeśli ciąg ma dokładnie „10”, zastąp go drugim wierszem.

m`^10$
>Katamari Damacy,Yuu Miyake

Jeśli ciąg ma dokładnie „11”, zastąp go drugim wierszem.

m`^11$
>Hey Jude,The Beatles

Jeśli ciąg znaków pasuje [0-9].+, zastąp go drugim wierszem. Nie dotyczy to liczb jednocyfrowych, 10a 11ponieważ zostały one już zastąpione, ani żadnego z powyższych ciągów zastępczych.

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

Jeśli żadna z powyższych nie pasuje, ciąg znaków zaczyna się od liczby. Domyślnie Toto, Afryka.

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

Zastąp symbole zastępcze >oraz ,przez Song:i Artist:.

>
Song: 
,
$nArtist: 

5

JavaScript (ES6), 276 bajtów

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

Wyjaśnienie

Dane wejściowe mogą opcjonalnie zawierać jedną spację końcową.

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
)

Test


To nie działa na 9 na, generuje kamari.
Rɪᴋᴇʀ

@RikerW Naprawiono. Zapomniałem przecinka ...
user81655

4

PowerShell, 278 bajtów

  • Może obsłużyć dowolną ilość białych znaków
  • Żadnego wyrażenia regularnego!
  • Niejawne rzutowanie 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'/')}

Bez golfa

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

Stosowanie

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

Chociaż ten jest dłuższy niż moje inne zgłoszenie, ten jest prosty i prawie bez golfa, więc i tak go załączyłem.

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

Jak to działa:

Jeśli dane wejściowe są prawidłowe, wydrukuj je bez zmian. Jeśli nie, nic nie drukuj.

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

Policz słowa.

wc -w

Prosta tabela wyszukiwania Song:i Artist:są przechowywane w zmiennych.

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

Wiem, że minęło trochę czasu, ale regex można skrócić ^(na ?)+$.
Kevin Cruijssen

1

Python 453 440 406 380 bajtów

EDYCJA: Dzięki Cyoce za zmniejszenie 13 bajtów!

EDYCJA: Jeszcze raz dziękuję Cyoce!

EDYCJA: Dzięki RainerP. za pomoc w ulepszeniu algorytmu w niektórych nieważnych przypadkach.

To jest przybliżony szkic programu w języku Python. Wierzę, że można go zdecydowanie zagrać w golfa, może do 300-400 bajtów. Ale wkrótce nad tym popracujemy.

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]

Wypróbuj tutaj!


Zamiast tej długiej listy użyj"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

Ponadto: zamiast if i not in ["n","a"," "]: ...wierzę, że można użyć if i not in 'na ': .... Dodatkowo if f==0: somecode; else: somemorecodemożna zmniejszyć do if f: somemorecode; else: somecode(0 to Falsy)
Cyoce

Co więcej (powinienem umieścić je wszystkie w jednym, no cóż): masz "\nArtist:"trzy razy. spróbuj ustawić zmienną, np A="\nArtist:", a następnie używając Azamiast ciągiem znaków. To samo można zrobić z "Song:". Myślę też, że if n<8or n==9:f=10można to przenieść na szczyt instrukcji if i zmienić naif n!=8:f=10
Cyoce

Twój program nie wykrywa nieprawidłowych danych wejściowych. Dane wyjściowe są Batman Themezamiast Africadla na na na nan na na na na.
Rainer P.

@RainerP. Dziękuję ... Wiedziałem, że czegoś mi brakuje ... Pracuję teraz nad zaktualizowanym algorytmem
TanMath

1

Julia, 325 bajtów

Prawdopodobnie można by dalej grać w golfa.

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

Wiem, że minęło trochę czasu, ale regex można skrócić ^(na ?)+$.
Kevin Cruijssen

Ponadto, kontrole można skrócić stosując trochę <i >zamiast ==: &&(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"). Off-topic: Podoba mi się twój awatar. Skończyłem oglądać SAO w zeszłym tygodniu. ;)
Kevin Cruijssen

1

Rdza, 501 477 bajtów

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

Bez golfa

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

Edycja: usunęła niepotrzebny ciąg do i napisała adnotacje


1

Perl 5 -pa , 248 bajtów

$_=/^(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

Wypróbuj online!


1

Perl 5 , 312 292 bajtów

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

Wypróbuj online!

Nie golfowany:

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

Brakowało mi niektórych przypadków, pracuję teraz nad poprawką
pslessard

1

C (gcc) , 403 395 370 365 bajtów

-8 -5 bajtów dzięki pułapkowi cat

Tak proste, jak to tylko możliwe.

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

Wypróbuj online!


0

Java 8, 353 bajtów

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

Wyjaśnienie:

Wypróbuj 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"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.