Довідка! У мене більше домашніх завдань!


18

Мій вчитель був більш ніж незадоволений моїм марсіанським домашнім завданням . Я дотримувався всіх правил, але вона каже, що те, що я випускаю, було химерним ... коли вона вперше подивилася на це, вона була дуже підозрілою. "Усі мови повинні дотримуватися закону Зіпфа, бла-бла-бла" ... Я навіть не знав, що таке закон Зіпфа!

Виявляється, закон Зіпфа стверджує, що якщо побудувати логарифм частоти кожного слова на осі y та логарифм "місця" кожного слова на осі x (найбільш поширений = 1, другий найбільш поширений = 2, по-третє, найчастіше = 3 і так далі), тоді на графіку буде показана лінія з нахилом приблизно -1, дати або взяти приблизно 10%.

Наприклад, ось сюжет для Мобі Діка:

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

Вісь x - це п яте найпоширеніше слово, вісь y - це кількість випадків n- го найпоширенішого слова. Нахил лінії близько -1.07.

Тепер ми покриваємо венеціанську. На щастя, венеціанці використовують латинський алфавіт. Правила такі:

  • Кожне слово повинно містити принаймні одну голосну (a, e, i, o, u)
  • У кожному слові може бути до трьох голосних підряд, але не більше двох приголосних підряд (приголосний - будь-яка літера, яка не є голосною).
  • Немає слів довше 15 літер
  • Необов’язково: групуйте слова на речення довжиною 3-30 слів, розмежовані періодами

Оскільки вчитель відчуває, що я обдурив моє марсіанське домашнє завдання, мені було призначено написати твір довжиною принаймні 30 000 слів (на венеціанській мові). Вона перевіряє мою роботу, використовуючи закон Зіпфа, тому при встановленні рядка (як описано вище) нахил повинен бути не більше -0,9, але не менше -1,1, і їй хочеться словниковий запас щонайменше 200 слів. Це ж слово не слід повторювати більше 5 разів поспіль.

Це CodeGolf, тому найкоротший код у байтах виграє. Будь ласка, вставте висновок на Pastebin або інший інструмент, де я можу завантажити його як текстовий файл.


Так, і якщо ви хочете, ви можете просто виконати речення з 32767 слів. Обмеження полягає в тому, що частота слів у реченні повинна відповідати закону zipf
Дж. Антоніо Перес

1
Традиційним прикметником для «від Венери» є венерал, але чомусь він зменшився у популярності. У науковій фантастиці зазвичай використовується венеціанська.
Пітер Тейлор

Я здогадуюсь, що складання списку слів після розподілу zipf та переміщення його має велику ймовірність створення послідовності з парами послідовних слів також після розподілу zipf. Більше того, при достатньому кількості різних слів у списку ймовірність повторення одного і того ж слова більше 5 разів поспіль була б дійсно мала. У випадку, якщо я спробував такий підхід і вдалося скласти вагомий твір, чи було б це прийнято?
Лев

Ваша здогадка є розумною, хоча нахил буде складати -0,35
Дж. Антоніо Перес

Це все одно виглядатиме як пряма; це просто схил був би занадто великий
Дж. Антоніо Перес

Відповіді:


3

Математика, 102 байти

""<>RandomChoice[1/Range@215->Rest@Flatten@Outer[StringJoin,a={"v","a","e","i","o","u"},a,a,{" "}],8!]

Безіменна функція, яка не вводить і не повертає рядок, що складається з 40320 трибуквенних венеціанських слів з пробілами.

Outer[StringJoin,a={"v","a","e","i","o","u"},a,a,{" "}]створює 216 трибуквенних слів, можливо, використовуючи лише літери "vaeiou", кожне з яких має свій пробіл. Перше з цих слів, "vvv", не є венеційським, але Restвикидає його.

Тоді RandomChoice[1/Range@215->...,8!]робить 8! = 40,320 випадкових варіантів з отриманого списку в 215 слів з ваговими частотами, що визначаються зворотними колами перших 215 цілих чисел ( 1/Range@215). Нарешті, <>""...об'єднайте рядки в отриманому списку.

Вихід далеко не детермінований; один твір дав цей венеціанський нарис .

Математика, 129 байт

#2&@@@Sort[Join@@Table[{i,Rest@Flatten@Outer[StringJoin,a={"v","a","e","i","o","u"},a,a,{" "}]~Part~j},{j,215},{i,0,1,j/7!}]]<>""

Цей детермінований. Базовий набір з 215 слів однаковий, але тепер кожне слово повторюється в точну кількість разів (слово #j повторюється приблизно 7! / J разів), щоб змусити закон zipf дотримуватися. Тоді слова перемежовуються однаково, щоб уникнути повторів. (Уявіть, що кожне слово розкладено на лінійці, при цьому всі копії цього слова однаково розташовані; коли всі слова читаються в порядку, жодне конкретне слово не повториться багато, можливо, зовсім не.) Результат - це 30,117-слів Венеціанський нарис .


Не робить 8! псевдовипадковий вибір означає, що ви могли б закінчитися 6 повторними повторами одного і того ж слова?
Денніс

Так, теоретично.
Грег Мартін

@GregMartin Насправді ... есе, з яким ви пов’язані, не відповідає; vvaз'являється шість разів поспіль. Я думаю, що, можливо, існує більша проблема, але ... чи не слід оскаржувати відповіді кожного разу? (А якщо ні, то як ви намалюєте межу того, наскільки ймовірно, що вони повинні працювати?)
H Walters

Це справедлива критика, і мені цікаво подивитися, як це відбувається.
Грег Мартін

2

05AB1E ,34 33 32 байти

525DL/9*vNy<FD}})žMDâžNâJè3ô.rðý

525DL                            Yield [1, ..., 525]
     /                           Yield [525/1, ..., 525/525]
      9*                         Yield [4725/1, ..., 4725/525]. It's the number of occurences of each word. The sum of this array is greater than 30000
        v                        For each value (y = value, N = iteration counter starting from 0)
         N                       Push iteration counter
          y<FD}                  Push an array of "int(value)" times the iteration counter
               }                 End for
                )                Wrap everything in an array. At this point the array countains the sorted indices of all words that matches the frequency specs
                 žM              Push "aeiou"
                   Dâ            Cartesian product with itself (["aa", "ae", ...])
                     žN          Push the consonants
                       âJ        Cartesian product and join the values to make valid venutian words
                         è       Compute a big string with all words that correspond to the formerly computed indices
                          3ô     Since all words are concatenated, separate them into blocks of 3 letters
                            .r   Shuffle
                              ðý Join with whitespaces and implicitly display

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

Я думаю, це все ще досить гольф! Наприклад, числові константи і vNy<FD}можуть бути зіграні.

Приклад виводу

Як це працює?

Він генерує всі комбінації слів, слідуючи правилу "голосний + голосний + приголосний", що робить 525 унікальних дійсних слів (понад 200). Потім він прив'язує до кожного з них частоту, яка задовольняє закону, f(x) = 4725/xдеx- це ранг поточного слова, починаючи з 1 і закінчуючи на 525. Потім частоти нормалізуються та примножуються, щоб було не менше 30000 слів. Цей код завжди містить 32074 слів, щоб зробити причетні константи погратими (див. Пояснення до коду). Таким чином, кожне слово повторюється кількість разів, що відповідає частоті одного і того ж слова. Нарешті слова перетасовують. Однак це не гарантує, що слово ніколи не повторюється п'ять разів поспіль. Отже, програми генерують більше, ніж потрібно 200 унікальних слів, щоб зменшити ймовірність повторення слова п'ять разів поспіль. Зверніть увагу, що цей код завжди генерує одну і ту ж послідовність слів. Єдине, що відрізняється між двома пробіжками - результат операції переміщення.

Як оцінити частоту?

Я зробив простий код Python3, який бере текст у файлі під назвою "вихід" (з точки зору алгоритму, це має сенс!) І виводить на "stats.csv".

from collections import Counter
from math import log10

with open("output", "r") as f:
    with open("stats.csv", "w") as stats:
        words = f.read().split()
        freqs = Counter(words)
        freqs = sorted([(i,freqs[i]) for i in freqs],key=lambda x:-x[1])

        print(len(words), "words")
        stats.write("logX;logF\n")
        for i, (key, f) in enumerate(freqs):
            stats.write(str(log10(i+1))+";"+str(log10(f))+"\n")

Який код завжди дає такий розподіл для мого коду: Закон частоти

Так ухил становить -1.0138. Це значення зараз менш близьке до -1, ніж ухил попереднього коду, але воно все ще задовольняє обмеженням нахилу.


Дякуємо вам за те, що сценарій оцінює частоту, зауважте, що у вас є додатковий `в кінці. Крім того, чому ви використовуєте крапки з комою як роздільники? csv зазвичай означає значення, розділені комами;)
Лев

1
Так, ти прав, ха-ха! Я заплутався з відміткою на секунду. Спочатку я використовував вбудований код, а потім зрозумів, що більш доцільно використовувати блок коду, але я забув видалити зайвий `. Я використовую крапки з комою як роздільники csv, тому що я французький, а деякі програмні продукти або компанії використовуються для розміщення десяткових знаків комами замість крапок, як це робимо з рукописними десятковими значеннями. Хоча я завжди використовую крапку для відділення цілої частини від дробової частини, я використовую крапку з комою, не задумуючись. Але еге, і ssv чудово;)
Доступний

0

Bash / Core Utils, 122 110 байт

for w in {b,c,d}{a,e,i}{f,g,h}{o,u,a}{j,k,l};{ let ++x;yes $w|head -$[5575/x];}|shuf --random-source=<(yes ae)

Розгорнуто:

for w in {b,c,d}{a,e,i}{f,g,h}{o,u,a}{j,k,l};{
    let ++x
    yes $w|head -$[5575/x]
}|shuf --random-source=<(yes ae)

for wЦикл генерує 243 різних слів. let ++x;з кроком, спочатку не встановленим x (за правилами арифметичного вираження під час першого виконання, xтрактується як 0, і таким чином його збільшення встановлюється у 1). Наступний рядок, таким чином, генерує наступні слова на частоті 5575 / x для наближення частоти zipf.

Наступний крок - це перестановка детерміновано, щоб відповідати вимозі повторення; незважаючи на --random-sourceте, що настільки велике ім'я прапора, використання його з шуфом перемагає кількість руків, що котять селекторний модуль. yes aeнасправді найкоротший фіксований "випадковий" пристрій, який я виявив, що відповідає.

Це породжує цей 33729 словесний нарис [пастбін] .

Bash / Core Utils, 96 84 байт (не конкуруючий)

Для недетермінованого підходу просто відріжте прапори shuf:

for w in {b,c,d}{a,e,i}{f,g,h}{o,u,a}{j,k,l};{ let ++x;yes $w|head -$[5575/x];}|shuf

Аналіз

Нахил zipf налаштований на прямий. Використання Excel для побудови на логарифмічних масштабах:

Учитель повинен помітити нахил zipf = -1.000764.

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