Яку пісню грає?


33

Натхненний цим xkcd

enter image description here

Ти працюєш для Шазама і у них є проект для вас. Деякі клієнти скаржаться на те, що їх додаток займає занадто багато місця на телефоні, тому вони хочуть, щоб ви кодували легку версію програми. На жаль, ваш існуючий код може зрозуміти лише слово "na", і ви повинні відправити незабаром. Це добре, ми зробимо найкраще з того, що у нас є.

Змагання

Ви повинні написати повну програму, яка приймає введення користувача або бере аргумент командного рядка, і надрукувати назву та виконавця пісні. Оскільки ми намагаємося виправити клієнтів, які скаржаться на розмір програми, ваш код повинен бути якомога коротшим. Вхід буде рядком, що складається повністю з na, з єдиним пробілом між ними. Малі та великі літери - довільні. Це вважається допустимим вводом: Na Na nA na NAЦе недійсний вхід:nah nah NA naNa banana Ви повинні визначити, яка пісня відтворюється, і роздрукувати її саме в такому форматі:

Song: <trackname>
Artist: <artist>

Якщо вхід рівно 8 на, це збігається з двома окремими піснями, тому ви повинні надрукувати обидві:

Song: Batman Theme
Artist: Neal Hefti

і

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

Якщо вхід рівно 10 н, потрібно надрукувати:

Song: Katamari Damacy
Artist: Yuu Miyake

Якщо введення рівно 11 н, потрібно надрукувати:

Song: Hey Jude
Artist: The Beatles

Якщо вхід становить 12 або більше, потрібно надрукувати

Song: Land Of 1000 Dances
Artist: Wilson Pickett

Нарешті, якщо введення недійсне, менше 8 na, або будь-яке зі слів не "na", програма не розуміє музику. Тож логічно, є лише одна пісня, якою вона могла бути. Ви повинні надрукувати:

Song: Africa
Artist: Toto

Як завжди, застосовуються стандартні лазівки, і найкоротша відповідь у байтах виграє.


2
чудова історія фону!
TanMath

Хіба не Ей Джуд 12 naс? Я просто слухав його і думав, що це (з точки зору тривалості нот) quarter quarter quarter quarter / eighth sixteenth sixteenth quarter-quarter-quarter / eighth sixteenth quarter-quarter-quarter, що становить 12 naс.
Арктур

4
@Ampora onnnnnnnnne-one-three-one-a-two-threeeeeeeeeee-one-a-two-threeeeeeee-hey-judeточно 11
Кінтопія,

1
Бетмен - na na / na na / na na / na naх2 batman. Я помітив, що вдруге побачив комічне.
wizzwizz4

2
3 роки вже пізно, щоб змінити виклик, але я заперечую, що тема катамарійської шкоди має назву "Катамарі на скелях" (або якщо ви пурист, це офіційно "Катамарі на скелях ~ Головна тема") і таким чином не слід перераховувати лише як "Пошкодження Катамарі"!
Значення чорнила

Відповіді:


7

Сітківка , 242

Спробуйте в Інтернеті!

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: 

Як це працює:

Прапор IgnoreCase + прапор режиму Grep + Regex ^na( na)*$. Якщо вхід правильний, надрукуйте його як є. Якщо ні, нічого не друкуйте.

iG`^na( na)*$

Прапор IgnoreCase + Прапор відповідності режиму + Regex na. Порахуйте "na" s та надрукуйте число.

iM`na

Якщо рядок точно "8", замініть другим рядком.

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

Якщо рядок точно "10", замініть другим рядком.

m`^10$
>Katamari Damacy,Yuu Miyake

Якщо рядок точно "11", замініть другим рядком.

m`^11$
>Hey Jude,The Beatles

Якщо рядок збігається [0-9].+, замініть другим рядком. Це не стосується однозначних чисел, 10і 11як вони вже були відремонтовані, ні будь-який із вищезазначених рядків заміни.

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

Якщо жодне з перерахованих вище не відповідає, рядок все ще починається з числа. Типово - Тото, Африка.

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

Замініть заповнювачі >і ,на Song:і Artist:.

>
Song: 
,
$nArtist: 

5

JavaScript (ES6), 276 байт

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

Пояснення

Введення може додатково містити один пробіл.

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
)

Тест


Це не працює для 9 на, це виводить kamari.
Rɪᴋᴇʀ

Виправлено @RikerW Я забув кому ...
користувач81655

4

PowerShell, 278 байт

  • Може обробляти будь-яку кількість пробілів
  • Жодного регексу!
  • Неявне набір клавіш 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'/')}

Безумовно

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

Використання

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

Хоча це довше, ніж моє інше подання, це одне просте і в значній мірі неперевершене, тому я все одно включив його.

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

Як це працює:

Якщо вхід правильний, роздрукуйте його як є. Якщо ні, нічого не друкуйте.

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

Порахуйте слова.

wc -w

Проста таблиця пошуку Song:і Artist:зберігається у змінних.

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

Я знаю, що минуло деякий час, але регекс можна скоротити ^(na ?)+$.
Кевін Кройсейсен

1

Python 453 440 406 380 байт

EDIT: Завдяки Cyoce за зменшення 13 байт!

EDIT: Ще раз дякую Cyoce!

EDIT: Завдяки RainerP. за те, щоб допомогти мені імпортувати алгоритм у певних недійсних випадках.

Це приблизний проект програми Python. Я вважаю, що це точно може бути гольф, можливо, до 300-400 байт. Але працювати над цим незабаром.

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]

Спробуйте тут!


Замість цього тривалого списку використовуйте"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

Також: замість того, if i not in ["n","a"," "]: ...я вважаю, ви можете використовувати if i not in 'na ': .... Крім того, if f==0: somecode; else: somemorecodeможна зменшити до if f: somemorecode; else: somecode(0 - Falsy)
Cyoce

Навіть більше (я мав би поставити це все в одному, о, добре): у вас "\nArtist:"три рази. спробуйте встановити змінну, наприклад A="\nArtist:", потім використовуючи Aзамість літерального рядка. Те саме можна зробити і з "Song:". Крім того, я думаю, що if n<8or n==9:f=10це можна перенести на вершину висловлювань if і змінити наif n!=8:f=10
Cyoce

Ваша програма не може виявити недійсний вхід. Результат Batman Themeзамість Africaдля na na na nan na na na na.
Райнер П.

@RainerP. Дякую ... Я знав, що мені щось не вистачає ... Зараз я працюю над оновленим алгоритмом
TanMath

1

Julia, 325 bytes

Probably could be golfed further.

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

I know it's been a while, but the regex can be shortened to ^(na ?)+$.
Kevin Cruijssen

Also, the checks can be shortened a bit by using < and > instead of ==: &&(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: I like your Avatar. Finished watching SAO last week. ;)
Kevin Cruijssen

1

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

Edit: removed an unnecessary to_string and type annotations


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

Try it 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

Try it 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 $_

I missed some cases, working on a fix now
pslessard

1

C (gcc), 403 395 370 365 bytes

-8 -5 bytes thanks to ceilingcat

Pretty much as straight-forward as can be.

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

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

Explanation:

Try it 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"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.