Код гольфу для моїх справжніх друзів


35

... і справжній гольф для моїх друзів з кодом.

Це виклик, заснований на однорічному коміксі XKCD, який складається здебільшого із тостів (пародій перших у комічному) за чітким малюнком, але з деякими незначними варіаціями.

Ваше завдання полягає в тому, щоб написати програму (або функцію), яка приймає першу половину будь-якого тосту з коміксу (все до і включаючи friends) як вхід (через stdin або аргумент функції) і виводить (або повертає) точний текст друга половина. Вам не доведеться обробляти недійсний ввід, застосовуються стандартні лазівки, найкоротший код в байтах виграє.

Приклади

Щоб допомогти тим, хто не хоче копіювати тости з будь-якого місця, ось їх усі, розділені на вхід та вихід.

Input: Champagne for my real friends
Output: and real pain for my sham friends!

Input: Pseudopods for my real friends
Output: and real pods for my pseudo-friends!

Input: Petticoats for my real friends
Output: and real coats for my petty friends.

Input: Loosestrife for my real friends
Output: and real strife for my loose friends!

Input: Ladybugs for my real friends
Output: and real bugs for my lady friends!

Input: Single-payer for my real friends
Output: and RealPlayer for my single friends.

Input: Tumbleweeds for my real friends
Output: and real weed for my Tumblr friends!

Input: Fauxhawks for my real friends
Output: and real hawks for my faux friends!

Input: Platonic solids for my real friends
Output: and real solids for my platonic friends!

Я думаю, у вас є друкарська помилка Single-payer(замість Single-player).
Кевін Кройсейсен

4
Кевін: Ні. Це дійсно так Single-payer.
ivzem

@KevinCruijssen - Це може бути помилка друку, але якщо так, то це Randall @ XKCD, а не ivzem. Там обговорюється на Explain xkcd . Крім того, ivzem - як тільки я побачив заголовок у списку HNQ, я був впевнений, що ви посилаєтесь на цей комікс. Молодці!
Бобсон

Відповіді:


18

Сітківка , 119 байт

Попередня версія не керувала правильно простором у "платонічних твердих тілах", ця працює і є коротшою :)

ew
rw
eds
ed
(\w+) ?([^oatr ]\w{3}.+)real
and real $2$1
C
S
gne
in
o 
o-
ti
ty
T`TL`Tl
p\w+y.+
$&.
s$
s!
real -p
RealPl

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

Це перетворює вхід у вихід через ряд підстановок.

Найцікавіша частина - це заміна (вид гольфу-регексу):

(\w+) ?([^oatr ]\w{3}.+)real
and real $2$1

Що робить майже всю роботу, розділяючи перше слово, розміщуючи його шматки в потрібних місцях, видаляючи зайві пробіли та будуючи структуру виводу. Для правильної роботи з тестовим випадком "Tumbleweeds" це залежить від попередньої заміни "eds" -> "ed".

Решта в основному складається із підстановок, які стосуються особливих випадків. Інші цікаві частини:

T`TL`Tl

Це перетворює все, крім "T" (для Tumblr) на малі регістри.

p\w+y.+
$&.
s$
s!

Це ставить "". в кінці кожного речення, що містить слово з буквою «у» після букв «р» («дрібниця» і «платник» на практиці). Тоді розміщуємо "!" в кінці всіх речень, що закінчуються на "s" (усі інші).


Це надрукує додатковий простір після platonic. Запропоновано виправити: TIO (+5 байт)
математика наркоман

1
@math_junkie Дякую, я завантажив нову версію, яка виправляє проблему з пробілами і ще коротше :)
Лев,

10

Python 2, 291 269 293 255 247 байт

Дякуємо, що Erik the Outgolferзаощадили 22 байти!

+24 байти для обліку деяких виходів, що закінчуються .замість!

lambda x:'and '+['real '+'pain%ssham ,pods%spseudo-,coats%spetty ,strife%sloose ,bugs%slady ,weed%sTumblr ,hawks%sfaux ,solids%splatonic '.split(',')['noarsekc'.find(x[7])],'RealPlayer%ssingle ']['-'in x]%' for my '+x[-7:]+'!.'['-'in x or'tt'in x]

Просте рішення для початку. Перевіряє восьму букву вводу, як це запропоновано в коментарях, і шукає відповідний вихід у словнику масиву.

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


Можливо, ви забули Single-payer for my real friends...
Матьє Родік

@MathieuRodic Ні, це цілком навмисно. RealPlayerце особливий випадок
математика наркоман

На жаль, вибачте, занадто швидко читайте
Матьє Родич

6

SOGL , 143 байти

_╔x⅜²‘,8WWAa"⅞+1Tλ²⅞ƨ◄…χŗbdŗu8ņ∑Ι⅓I‼hzΔμō┘═q‼xΘ▼²ηpG⅔─┌¡↕+wd÷[≈┐α┌ļ○(‚δΦEΤα{‚φ▒k׀:╚s&⅛↑»‘ |Θwθ1w"ρ└⁸‘S∆∫⁴‘a1>*+oo"¤Ε○Φr‘o2w _@ŗo"æn‘o"χ}49⁶‘aWT

Цей рядок використовується як основна частина. "|" - це роздільники та "_" - заповнювачі місця, тому розділення буде працювати правильно.

RealPlayer single_|weed Tumblr_|strife loose_|bugs lady_|pods pseudo-|pain sham_|solids platonic_|coats petty_|hawks faux_

Приклад введення: "Платонічні речовини для моїх справжніх друзів" Пояснення:

..‘,8WWAa"..‘ |Θwθ1w"..‘S∆∫⁴‘a1>*+oo"..‘o2w _@ŗo"..‘o"..‘aWT  strings shortened
..‘                                                           push "personcake" (the indexing string) ["personcake"]
    8W                                                        get the 8-th char                       
   ,                                                           from the input                         ["personcake", "c"]
      W                                                       get its in "personcake" (1-indexed)     [7]
       Aa                                                     save on variable A                      [7]
         "..‘                                                 push the long string                    [7, "RealPlayer...faux_"]
              |Θ                                              split on "|"                            [7, ["RealPlayer single_", ..., "hawks faux_"]]
                w                                             get the Ath item of the array           [["..."], "solids platonic_"]
                 θ                                            split on spaces                         [["..."], ["solids", "platonic_"]]
                  1w                                          get the 1st item                        [["..."], ["solids", "platonic_"], "solids"]
                    "..‘                                      push "and "                             [["..."], ["solids", "platonic_"], "solids", "and "]
                        S∆∫⁴‘                                 push "real "                            [["..."], ["solids", "platonic_"], "solids", "and ", "real "]
                             a1>*                             multiply by A(index) > 1                [["..."], ["solids", "platonic_"], "solids", "and ", "real "]
                                 +                            join together                           [["..."], ["solids", "platonic_"], "solids", "and real "]
                                  o                           output                                  [["..."], ["solids", "platonic_"], "solids"]
                                   o                          output (the 1st item of the array)      [["..."], ["solids", "platonic_"]]
                                    "..‘o                     output " for my "                       [["..."], ["solids", "platonic_"]]
                                         2w                   get the 2nd item of the array           [["..."], ["solids", "platonic_"], "platonic_"]
                                            _@ŗ               replace "_" with " "                    [["..."], ["solids", "platonic_"], "platonic "]
                                               o              output that                             [["..."], ["solids", "platonic_"]]
                                                "..‘o         output "friends"                        [["..."], ["solids", "platonic_"]]
                                                     "..‘     push ".!!!!!!.!"                        [["..."], ["solids", "platonic_"], ".!!!!!!.!"]
                                                         aW   get the Ath item                        [["..."], ["solids", "platonic_"], "!"]
                                                           T  output, disabling implicit output       [["..."], ["solids", "platonic_"]]

6

Python 3 , 788 , 403 , 359 396 байт

Остання версія

Це вже моя п'ята спроба. Мені вдалося вдвічі менше розміру моєї оригінальної програми. Тепер він включає відсутні "-", і я вважаю, що це повне рішення. Досі підозрюю на громіздкій стороні; але набагато ближче до мети. У мене була велика допомога . Дякую за всі корисні вказівки.

s=input()
x=0
l= "Ch,pain,Sham,Ps,pods,psuedo-,Pe,coats,petty,Lo,strife,loose,La,bugs,lady,Si,RealPlayer,single,Tu,weed,Tumblr,Fa,hawks,faux,Pl,solids,platonic".split(",")
a,b,c,d,e,f,g,h = " and real","for my","friends",".!","print(a,l[p+1],b,l[p+2]",",c+d[0])","+c+d[1])",",c+d[1])"
for p in range(0,27,3):
 x+=1
 if s[:2] == l[p]:
  if x == 2: eval(e+g)
  else: eval(e+f if x in(3,6) else e+h)

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


Оригінальна публікація

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

phraseList= [   ("Champagne","pain","Sham"), 
                ("Psudeopods","pods","psuedo-"), 
                ("Petticoats","coats","petty"),
                ("Loosestrife","strife","loose"),
                ("Ladybugs","bugs","lady"),
                ("Single-payer","coats","petty"),
                ("Petticoats","RealPlayer","single"),
                ("Tumbleweeds","weed","Tumblr"),
                ("Fauxhawks","hawks","faux"),
                ("Platonic solids","real solids","platonic")
                ]

for phrase in phraseList:
    print("Input: ",phrase[0], "for my real friends.")
    if "-" in phrase[2]:
        print("Output: and real", phrase[1], "for my", phrase[2]+ "friends!")
    else:
        print("Output: and real", phrase[1], "for my", phrase[2], "friends!")

3
З довідкового центру : Усі рішення проблем: [...] Будьте серйозним претендентом на виграшні критерії, які використовуєте. Наприклад, для участі в змаганні з кодом з гольфу потрібно грати в гольф, а запис на змагання з швидкості повинен зробити певну спробу швидкою.
Ерік Аутгольфер

1
Привіт і ласкаво просимо на сайт. Це питання з кодовим гольфом, яке вимагає докласти зусиль, щоб мінімізувати довжину коду. Вам слід видалити зайвий пробіл та перейменувати змінні довжиною 1 символ.
Пшеничний майстер

Ви можете скласти весь список виразів в один рядок, зменшити відступ до одного пробілу, скласти відбитки в один рядок з if і else, а пробіли в друкуванні не потрібні. У будь-якому разі, я не знаю, чи вам дозволяється просто друкувати всі виходи;)
Мега Ман

1
Привіт! Схоже, це ваша перша відповідь на код гольфу. На жаль, ви, схоже, неправильно зрозуміли питання, особливо таблицю "Приклади" внизу, яка просто показує, як кожен вхід повинен відображати відповідний вихід. Наразі ваша програма просто друкує цю таблицю. Так само стандартною практикою є розміщення коду в блоці коду (виберіть його та натисніть {}) для кращої читабельності та згадування вашої мови вибору та кількості байтів, оскільки цей сайт є більше схожий на конкуренцію, ніж на сайт із питань питань і відповідей ._ Мастер пшениці вже зробив це, тож це краще
ivzem

Привіт і ласкаво просимо до PPCG. Ви можете втратити багато байт, видаливши пробіли та використовуючи змінні однієї літери. Я пам’ятаю, коли я вперше почав тут проходити певний час, щоб звикнути. Я думаю, ти схожий на мене. Ви витрачаєте багато часу на написання читаного коду. Як я вже казав, ласкаво просимо до PPCG та нового світу;)
ElPedro

6

Рода , 299 292 288 259 байт

4 байта зберігається завдяки @fergusq для використання ,замість ..в pushзвітності

Байти збережено завдяки @fergusq, який показує мені шлях indexOf

h a{r=indexOf(a[7:8],"noarspekc")A="pain>pods>coats>strife>Player>bugs>weed>hawks>solids>sham >pseudo->petty >loose >lady >single >Tumblr >faux >platonic >!>!>.>!>!>.>!>!>!"/">";["and "];["Real"]if[r=4]else["real "];[A[r]," for my ",A[r+9],"friends",A[r+18]]}

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

Так близько до Python ... так близько .... Ваш хід, Python.

Пояснення

h a{
  r=indexOf(a[7:8],"noarspekc")  /*Gets the index of the character in this string*/
  /*Variable A contains all the unique words for each test case*/
  A="pain>pods>coats>strife>Player>bugs>weed>hawks>solids>sham >pseudo->petty >loose >lady >single >Tumblr >faux >platonic >!>!>.>!>!>.>!>!>!"/">"
  ["and "]
  ["Real"]if[r=4]else["real "]   /*RealPlayer*/
  [A[r]," for my ",A[r+9],"friends",A[r+18]]   /*Print everything using var A*/
}

Чи можете ви зберегти один байт, використовуючи рядову інтерполяцію в останньому операторі? Редагувати: насправді найкоротший спосіб - це, мабуть, просунути багато потоків до потоку замість одного, тобто. замінити ..на ,.
fergusq

@fergusq Дякую за пораду!
Kritixi Lithos

Також ви можете просто використовувати r=indexOf(a[7:8],"noarspekc").
fergusq

@fergusq Ах, я не знав, що існує така побудова. Спасибі!
Kritixi Lithos

5

JavaScript (ES6), 230 228 221 216 байт

s=>'and '+((n='paonrsekc'.search(s[7]))?'real ':'')+'RealPl740s5 /450p3y /540p5-/pain0s3 /460l4 /340l3 /540T4r /350f3 /860p7 '.split`/`[n].replace(/\d\d?/g,n=>s.substr(n/10+1,n%10)||' for my ')+'friends'+'.!'[+(n>1)]

Тест


3

PHP, 202 220 204 203 байт

and real <?=[pods,solids,hawks,strife,RealPlayer,pain,bugs,weed,coats][$q=md5($argv[1].LnI)%9].' for my '.[pseudo,platonic,faux,loose,single,sham,lady,Tumblr,petty][$q].' -'[!$q].friends.'.!'[!$q||$q&3];

3

Perl, 173 168 байт

Видаляючи нові рядки та відступи, це стає 173 байтом коду Perl5. Безсоромно вкрав перший регепс з відповіді Лео. (Мій був на кілька символів довше)

sub f{
  my($_)=@_;
  s,(\S+[oieyxm ])(\S{4}.+)real,and real $2\l$1,;
  s,gne,in,;
  s,ch,sh,;
  s,ti,ty,;
  s,eds,ed,;
  s,tumble,Tumblr,;
  s,real -p,RealPl,;
  s,o ,o-,;
  s,c ,c,;
  /ng|tt/?"$_.":"$_!"
}

Для версії perl5> = 5.14 ще 5 байт можна відтерти за допомогою eval та нового модифікатора заміни regexp. Закінчується 168 байтами:

sub f{my($_)=@_;eval's,(\S+[oieyxm ])(\S{4}.+)real,and real $2\l$1Xgne,inXch,shXti,tyXeds,edXtumble,TumblrXreal -p,RealPlXo ,o-Xc ,c,;/ng|tt/?"$_.":"$_!"'=~s/X/,;s,/gr}

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


2

C, 367 байт

Не закінчилося так коротко, як здавалося б.

i,j,c;f(char*s){c=s[7]-97;char t[9],u[200];char*r=s;s+=j=c&&c-17?c-10&&c-18?c-2?5:8:3:4;for(i=0;*++s-32;t[i++]=*s);t[c-4?i:i-1]=0;for(i=0;*r++-t[0];)u[i++]=*(r-1);u[i]=32;u[i+1]=0;u[0]+=32;u[c?i:i-1]=c?c-2?c-14?32:45:0:121;printf("and %s%s for my %sfriends%c",c-15?"real ":"RealPlayer",c-15?c-13?t:"pain":"",c-13?c-4?c-17?u:"loose ":"Tumblr ":"sham ",c&&c-15?33:46);}

2

Java 7, 585 553 байт

import java.util.*;String c(String s){Map m=new HashMap(){{put("Ch","pain");put("Ps","pods");put("Pe","coats");put("Lo","strife");put("La","bugs");put("Si","Player");put("Tu","weed");put("Fa","hawks");put("Pl","solids");put("Ch1","sham ");put("Ps1","pseudo-");put("Pe1","petty ");put("Lo1","loose ");put("La1","lady ");put("Si1","single ");put("Tu1","Tumblr ");put("Fa1","faux ");put("Pl1","platonic ");}};String r=s.substring(0,2);int c=r.charAt(1);return"and "+(c=='i'?"Real":"real ")+m.get(r)+" for my "+m.get(r+1)+"friends"+(c=='i'|c=='e'?'.':'!');}

-32 байти завдяки @Zircon .

Однозначно можна пограти в гольф, скориставшись чимось іншим, ніж карта ..

Пояснення:

import java.util.*;            // Import required for the Map & HashMap
String c(String s){            // Method with String parameter and String return-type
  Map m=new HashMap(){{        //  The Map
    put("Ch","pain");put("Ps","pods");put("Pe","coats");put("Lo","strife");put("La","bugs");put("Si","Player");put("Tu","weed");put("Fa","hawks");
                               //  Add mapping from first two characters with first word
    put("Ch1","sham ");put("Ps1","pseudo-");put("Pe1","petty ");put("Lo1","loose ");put("La1","lady ");put("Si1","single ");put("Tu1","Tumblr ");put("Fa1","faux ");put("Pl1","platonic ");
                               //  Add mapping from first two characters + "1" with second word (+ space or '-' for edge-case `pseudo-friends`)
  }};                          // End of Map initialization
  String r=s.substring(0,2);   //  Get the first two characters of the input String
  int c=r.charAt(1);           //  Get the second character
  return "and "                //  return "and "
    + (c=='i'?"Real":"real ")  //   + "Real" or "real " for edge-case `RealPlayers`
    + m.get(r)                 //   + first word from Map
    + " for my "               //   + " for my "
    + m.get(r+1)               //   + second word from Map
    + "friends"                //   + "friends"
    + (c=='i'|c=='e' ? '.'     //   + '.' for edge-cases 'Petticoats' and 'Single-player
      : '!');                  //     or '!' for all other cases
}                              // End of method

Код тесту:

Спробуйте тут. (останнім часом помилка ideone.com, тому я зараз використовую TIO ..)

import java.util.*;
class M{
  static String c(String s){Map m=new HashMap();m.put("Ch","pain");m.put("Ps","pods");m.put("Pe","coats");m.put("Lo","strife");m.put("La","bugs");m.put("Si","Player");m.put("Tu","weed");m.put("Fa","hawks");m.put("Pl","solids");m.put("Ch1","sham ");m.put("Ps1","pseudo-");m.put("Pe1","petty ");m.put("Lo1","loose ");m.put("La1","lady ");m.put("Si1","single ");m.put("Tu1","Tumblr ");m.put("Fa1","faux ");m.put("Pl1","platonic ");String r=s.substring(0,2);int c=r.charAt(1);return"and "+(c=='i'?"Real":"real ")+m.get(r)+" for my "+m.get(r+1)+"friends"+(c=='i'|c=='e'?'.':'!');}

  public static void main(String[] a){
    System.out.println(c("Champagne for my real friends"));
    System.out.println(c("Pseudopods for my real friends"));
    System.out.println(c("Petticoats for my real friends"));
    System.out.println(c("Loosestrife for my real friends"));
    System.out.println(c("Ladybugs for my real friends"));
    System.out.println(c("Single-player for my real friends"));
    System.out.println(c("Tumbleweeds for my real friends"));
    System.out.println(c("Fauxhawks for my real friends"));
    System.out.println(c("Platonic solids for my real friends"));
  }
}

1
Я думаю, ви можете зберегти байти, використовуючи подвійну дужку ініціалізації та putзамість m.put.
Циркон

2

C (gcc) , 311 байт

Чіткі зразки, але так багато винятків. Все-таки повинен бути кращий шлях, ніж цей!

f(char*s){char*t="\"5$#(=931",*r[]={"pain", "sham","pods","pseudo","coats","petty","strife","loose","bugs","lady","Player","single","weed","Tumblr","hawks","faux","solids","platonic"};int i=strchr(t,*s^s[2])-t;printf("and %s%s for my %s%cfriends%c",i^5?"real ":"Real",r[i*2],r[i*2+1],i^1?32:45,i^5&&i^2?33:46);}

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

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