Код гольф для моих настоящих друзей

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!
ivzem
источник
Я думаю, что у вас есть опечатка Single-payer(вместо Single-player).
Кевин Круйссен
4
Кевин: Нет. Это действительно так Single-payer.
ивзем
@KevinCruijssen - Это может быть опечатка, но если это так, то это Рэндалл @ 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 Спасибо, я загрузил новую версию, которая исправляет проблему с пробелами и еще короче :)
Leo
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_"]]
dzaima
источник
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
Из справочного центра : все решения проблем должны: [...] быть серьезным претендентом на критерии победы в использовании. Например, для участия в соревновании по коду в гольф необходимо сыграть в гольф, а для участия в соревновании по скорости следует попытаться быть быстрым.
Эрик Outgolfer
1
Здравствуйте и добро пожаловать на сайт. Это вопрос кода, который требует от вас усилий, чтобы свести к минимуму длину вашего кода. Вы должны удалить ненужные пробелы и переименовать переменные длиной 1 символ.
Wheat Wizard
Вы можете поместить весь фразуList в одну строку, уменьшить отступ до одного пробела, поместить отпечатки вместе в одну строку с if и else, и пробелы в отпечатках не нужны. Во всяком случае, я не знаю, разрешено ли вам просто печатать все выходы;)
Mega Man
1
Здравствуйте! Похоже, это ваш первый кодовый ответ на гольф. К сожалению, вы, похоже, неправильно поняли вопрос, особенно таблицу «Примеры» внизу, которая просто показывает, как каждый вход должен отображаться в соответствующий выход. В настоящее время ваша программа просто печатает эту таблицу. Кроме того, стандартная практика заключается в размещении вашего кода в блоке кода (выберите его и нажмите {}) для лучшей читаемости и упомяните ваш язык выбора и количество байтов, поскольку этот сайт больше похоже на соревнование, чем на сайт вопросов и ответов. Wheat Wizard уже сделал это, так что лучше
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]]}

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

Так близко к Питону ... так близко ... Твой ход, Питон.

объяснение

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*/
}
Kritixi Lithos
источник
Можете ли вы сохранить один байт, используя интерполяцию строк в последнем выражении? Изменить: на самом деле самый короткий путь, вероятно, состоит в том, чтобы выдвинуть в поток множество строк вместо одной, т.е. заменить ..на ,.
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)]

Тест

Arnauld
источник
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];
user63956
источник
3

Perl, 173 168 байт

Удаляя символы новой строки и отступы, это становится 173 байтами кода Perl5. Бесстыдно украл первое регулярное выражение из ответа Retina Лео. (У меня было несколько символов дольше)

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 и нового модификатора подстановки / r 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);}
Steadybox
источник
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);}

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

gastropner
источник