Какая песня играет?


33

Вдохновленный этим xkcd

введите описание изображения здесь

Ты работаешь на Shazam и у них есть проект для вас. Некоторые клиенты жалуются на то, что их приложение занимает слишком много места на телефоне, поэтому они хотят, чтобы вы запрограммировали облегченную версию приложения. К сожалению, ваш существующий код может понимать только слово «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», ваша программа не может понять музыку. Логично, что есть только одна другая песня, которая могла бы быть. Вы должны напечатать:

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
Quintopia

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. Подсчитайте «н» и выведите число.

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 так как они уже были repaced , ни какой - либо из вышеуказанных строк замены.

[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 na, это выводит камари.
Rɪᴋᴇʀ

@RikerW Исправлено. Я забыл запятую ...
user81655

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

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

использование

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

Хотя это и дольше, чем в моем другом представлении, это прямолинейно и в значительной степени ungolfed, поэтому я все равно включил его.

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 байт

РЕДАКТИРОВАТЬ: Спасибо Cyoce за сокращение 13 байтов!

РЕДАКТИРОВАТЬ: Еще раз спасибо Cyoce!

РЕДАКТИРОВАТЬ: Благодаря 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 - ложь)
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

Юлия, 325 байт

Вероятно, может быть в гольфе дальше.

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

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

Кроме того , проверка может быть сокращен немного, используя <и >вместо ==: &&(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"). Не по теме: мне нравится твой аватар. Завершил просмотр SAO на прошлой неделе. ;)
Кевин Круйссен

1

Ржавчина, 501 477 байт

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

Редактировать: удалил ненужную строку to_string и набрал аннотации


1

Perl 5 -pa , 248 байт

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

Попробуйте онлайн!


1

Perl 5 , 312 292 байта

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

Попробуйте онлайн!

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

Я пропустил некоторые случаи, работая над исправлением сейчас
pslessard

1

C (gcc) , 403 395 370 365 байт

-8 -5 байт, благодаря функциюcatcat

Довольно прямолинейно, насколько это возможно.

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

Попробуйте онлайн!


0

Java 8, 353 байта

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

Объяснение:

Попробуйте онлайн.

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.