A Spintax {Завдання | Проблема | Питання}


19

Стаття Спінінг за допомогою Spintax

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

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

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

{Hello|Hi there|Bonjour}, user! {What's up?|How are you?|Feeling alright?|I caught a fish!}

Як бачимо, секції рядка, які слід "закрутити", укладені у фігурні дужки, де окремі параметри розділені |символом. Ось кілька прикладів пропозицій, які це може дати.

Hi there, user! What's up?
Hello, user! How are you?
Bonjour, user! Feeling alright?
Hello, user! What's up?
Hi there, user! I caught a fish!

Ваша робота

Якщо ви вирішите прийняти це, ваша місія полягає в тому, щоб створити програму або функцію, яка займає вхідний рядок, який може містити або не містить Spintax , а потім надрукувати 5 версій рядка, випадково вибравши один з варіантів з кожного блоку параметрів. Можна зробити кілька припущень:

  1. Вам не потрібно буде обробляти вкладений Spintax ( {This|is {an|one}|example}).
  2. В |, {і }персонаж не будуть відбуватися в іншому місці, крім всередині блоку Spintax.
  3. Вам не потрібно перевіряти, чи відрізняються 5 вихідних пропозицій, якщо код вибирає параметри, використовуючи функцію випадкового числення вашої мови.
  4. Ви можете припустити, що вхід закінчується новим рядком.

Правила

  1. Немає стандартних лазівки

Тести

1. {A|The|One} {quick|magnificent|charming|lucky|fast|super|cool} {gold|tan|yellow|white|brown|silver} {beaver|packrat|cat|lion|tiger|fox|dog|wolf} {consumed|ate|pilfered} my {pastry|strudel|cake}.
-------------------------------------------
One cool brown wolf consumed my pastry.
...(3 more here)...
The charming yellow beaver ate my cake.
-------------------------------------------
2. This sentence is valid, and happens to have no Spintax!
-------------------------------------------
This sentence is valid, and happens to have no Spintax!
...(3 more here)...
This sentence is valid, and happens to have no Spintax!
-------------------------------------------
3. {beg|get|ton|sun|bun|can|top|big}{2|3|4|5}{A|B|C|D|E|F|G}{2|3|4|5|6|7}{at|as|be|ex|hi|}{!|#|%}
-------------------------------------------
top2F2hi%
...(3 more here)...
big3E4ex#

Четвертий тест можна знайти тут.


Це , тому виграє найменше кількість байтів.


2
Тепер, з невеликою зміною ... шалені вусики!
Геобіц

Яких типів символів ми можемо очікувати у введенні?
Sp3000

@ Sp3000 Все від ASCII 32-127. Єдине місце , де {, |, }збирається знайти у вхідному рядку, де є Spintax.
Каде

Відповіді:


8

Піт, 18

V5sOMcR\|scR\{cz\}

Спробуйте його онлайн тут

Пояснення:

V5sOMcR\|scR\{cz\}                     : z = input()
V5                                     : do this 5 times
              cz\}                     : split z on the } character
          cR\{                         : split each element of the resulting list on {
         s                             : join the list of lists back into a list of strings
     cR\|                              : split these strings on the | character
   OM                                  : Choose a random element from each inner list
  s                                    : join those choices, and print them

1
Боже мій, це було швидко!
Кейд

7

Рубі, 46

З прапором командного рядка -pзапустіть

($_*=5).gsub!(/{(.+?)}/){$1.split(?|).sample}

Прочитайте в рядку з останнім рядком. З'єднайте його 5 разів, вимкніть його на місці та виведіть результат. /{(.+?)}/- це регулярний вираз із лінивим кількісним показником: без цього ?він би відповідав крайньому лівому {та правому крайньому, }а не найближчому. $1є магічною змінною, що стосується першої групи захоплення у кожному матчі, тоді як ?|буквальна посилається на |персонажа. sampleце метод масиву, що повертає випадковий елемент.


6

CJam, 25 22 19 18 байт

q5*'}/{'{/~'|/mR}/

Цей код вимагає, щоб вхід містив зворотний новий рядок.

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Як це працює

q     e# Read from STDIN.
5*    e# Repeat the input five times.
'}/   e# Split at right curly brackets.
{     e# For each chunk:
  '{/ e#   Split at left curly brackets.
  ~   e#   Dump both chunks on the stack.
  '|/ e#   Split the right chunk at vertical bars.
  mR  e#   Select a chunk, pseudo-randomly.
}/    e#

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


6

Python 3, 110 байт

import re,random
exec('print("".join(random.choice(s.split("|"))for s in re.split("{(.*?)}",%r)));'%input()*5)

Розщеплення Regex, як і інші.

Пітон 3, 121 116 114 байт

from random import*
exec(("print(%r[:-1]);"%(input()+'"')).translate({123:"'+choice(['",124:"','",125:"'])+'"})*5)

Цей виконує відповідні заміни, потім оцінює їх. Якби не втеча від нахилів і апостроф, це виявилося б коротшим.

Наприклад, припустимо, у нас є Спінтакс

I {like|hate} {Python|C}.

В .translateвиконує кілька конверсій , щоб дати:

print('I '+choice(['like','hate'])+' '+choice(['Python','C'])+'.')

4

Perl, 50

$_=$_ x5;s/{(.*?)}/@r=split"\\|",$1;$r[rand@r]/ge

49символів +1для -p.

Це працює, попередньо встановивши $_5 речень. Тоді він робить глобальний пошук і заміну, де ми шукаємо кожну { | | }групу. Він розділяє групу на |, і вибирає випадковий елемент для заміни.

Виконати з:

echo '{A|The|One} {quick|magnificent|charming|lucky|fast|super|cool} {gold|tan|yellow|white|brown|silver} {beaver|packrat|cat|lion|tiger|fox|dog|wolf} {consumed|ate|pilfered} my {pastry|strudel|cake}.' | perl -pe'$_=$_ x5;s/{(.*?)}/@r=split"\\|",$1;$r[rand@r]/ge'

$_ x=5економить кілька байт.
Денніс

4

Страус v0.7.0 , 27 символів

{`{.*?}`{);(;"|/.,R*F=}X}5*

Пояснення:

{...}5*  repeat 5 times
  `{.*?}`  regex to match "spintax" sections
  {...}X   replace with...
    );(;     remove first and last characters (the curly brackets)
    "|/      split on |
    .,R*     multiply length of that array by a random number
    F=       take the floor of that and get the nth element of the array

.


4

Піп, 25 22 20 байт

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

L5P_@RR#_Ma^`}|{`^'|

Пояснення:

L5                    Loop 5 times:
          a^`}|{`     Split cmdline arg on curly braces using regex
                 ^'|  Split each item of the result on pipe (if there isn't one,
                        the result is a single-item list)
         M            Map this function to each item a in the result:
   _@RR#_             Calculate a random number between 0 and len(item)-1; use it to
                        index into item
  P                   Print the resulting list, concatenating elements together

17 байт (але не дійсне подання)

L5PRC_Ma^`}|{`^'|

Потрібна остання версія Pip, оновлена ​​після опублікування цього питання. Оператор RC (випадковий вибір) був запланований на деякий час, але я ніколи не замислювався над його реалізацією. : ^ (

Дізнайтеся більше про Pip


1
Серйозно? Ви пишете свою власну мову, щоб виграти змагання з гольфу?
Хлоя

3
@Chloe: CJam , GS2 , страус , PYG , Pyth , Retina і RS всіх мови гольф винайдених користувачами цього сайту.
Денніс

3

JavaScript ES6, 86 84 байт

f=s=>s.repeat(5).replace(/{(.+?)}/g,(_,e)=>(p=e.split`|`)[Math.random()*p.length|0])

Це очікує, що вхід матиме зворотний новий рядок. Він починається з повторення введення 5 разів, а потім замінює кожну рядок Spintax випадковим словом із неї, яке отримується шляхом розбиття |символів та вибору випадкового числа між 0 та довжиною отриманого масиву мінус 1. У цьому випадку, |0це лише коротший спосіб виконанняMath.floor . Дякую vihan1086, що нагадав мені про теги з тегами шаблону.

Сніппет стека нижче містить неперевершений і легко перевіряється код.

f=function(s){
  return s.repeat(5).replace(/{(.+?)}/g,function(_,e){
    return (p=e.split('|'))[Math.random()*p.length|0]
  })
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('input').value+'\n')};document.getElementById('run').onclick=run;run()
<input type="text" id="input" value="{A|The|One} {quick|magnificent|charming|lucky|fast|super|cool} {gold|tan|yellow|white|brown|silver} {beaver|packrat|cat|lion|tiger|fox|dog|wolf} {consumed|ate|pilfered} my {pastry|strudel|cake}." style="width: 400px;" /><button id="run">Run</button><br />
<pre id="output"></pre>


|0еквівалентно Math.floorне Math.round. Хоча саме цього ви хочете, як Math.roundби забезпечували нерівномірний розподіл.
Джордж Рейт

@GeorgeReith Ти маєш рацію, я мав намір поставити підлогу, але випадково поставив коло. Дякую
NinjaBearMonkey


2

Python 2, 139 байт

Додано два байти для лапок навколо вхідного рядка. Якщо вони не потрібні, дайте мені знати.

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

import re,random
s=input()
exec"print''.join(t*(t!=''and(t[0]!='{'))or random.choice(t[1:].split('|'))for t in re.split('({.*?)}',s));"*5

1

Java, 243 215 242 234 байт

int i,k;void f(String s){String a,b[],c=s;for(;k++<5;System.out.println(c),c=s)while((i=c.indexOf("{"))>=0){a=c.substring(i,c.indexOf("}")+1);b=a.replaceAll("\\{|\\}","").split("\\|");c=c.replace(a,b[(int)(Math.random()*b.length)]);}}

Знаходить рядки в дужках {}і замінює їх випадковим елементом з масиву рядків, створених розщепленням символом труби. (Я зрозумів трохи пізно, що треба було надрукувати п’ять речень: P)


1

Баш: 144 138 символів

IFS={} read -ap
w()(for o in "${p[@]}";{
[[ $o =~ \| ]]&&{
IFS=\| read -aa<<<"$o"
o=${a[RANDOM%${#a[@]}]}
}
echo -n "$o"
}
echo)
w
w
w
w
w

Проба зразка:

bash-4.3$ bash spintax.sh <<< "Look {ma'|daddy|mr. president}! No {bin|core|doc|find|mail}utils tools nor {Awk|Sed|jq|XML Starlet}!"
Look ma'! No docutils tools nor Awk!
Look daddy! No binutils tools nor XML Starlet!
Look mr. president! No docutils tools nor XML Starlet!
Look ma'! No docutils tools nor Awk!
Look mr. president! No binutils tools nor Sed!

1
Ви можете зберегти кілька байтів, використовуючи w()(...)замість w(){...}(дозволяє усунути пробіли), printfа не echo -nфігурні дужки замість doі done.
Денніс

Дякую, @Dennis. Знову. (На жаль, це не перший раз, коли я забуваю ці хитрощі.) Щодо того printf, це не вдасться у вхідному рядку, що містить "%", якщо я щось неправильно не зрозумів.
манатура

1

Javascript, 143 142 байти

a=prompt(b=5);for(c=[];b--;c.push(a.replace(/{(.+?)}/g,function(_,j){return (d=j.split("|"))[d.length*Math.random()|0]})));alert(c.join("\n"))

1

Python 3, 97 байт

Використання лямбда-функції при заміні регулярних виразів. Це дещо схоже на те, як я це робив у своєму модулі Spintax https://github.com/AceLewis/spintax, однак він не стосується вкладеного Spintax або втечі символів.

import re,random
print(re.sub("{(.*?)}",lambda x:random.choice(x.group(1).split('|')),input()*5))

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

import re,random
print(re.sub("{(.*?)}",lambda x:random.choice(x.group(1).split('|')),(input()+'\n')*5))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.