Підробляють прогноз


15

Прийшов новий суперкомп'ютер, що прогнозує погоду, і він не працює.

Тим часом ваш начальник хоче, щоб ви придбали техніків деякий час, підробляючи щоденні карти вітру.

Ваше завдання - намалювати сітку стрілок, що представляють напрямок вітру.

Сітка:

  • складається з квадратних плиток розміром 15 пікселів
  • 8 плиток на 8 плиток
  • 120px квадратний загальний
  • 000 фону

Кожна сітчаста плитка має 8 потенційних орієнтацій, що представляють напрямок вітру:

  1. Північ
  2. Північний Схід
  3. Схід
  4. Південно-Східний
  5. Південь
  6. На південний захід
  7. Захід
  8. Північний захід

Який має бути зображений так:

N N NE НЕ E Е SE SE S S SW SW W W NWСЗ

Карти повинні змінюватися поступово , щоб бути правдоподібними.

Це означає, що кожна плитка може відрізнятися від свого сусіда лише на один крок. Конкретно:

  • Плитка може відрізнятися лише на один приріст або декремент від кожної з 4 сусідніх плиток. (або 3 для бічних плиток, 2 для кутових плиток).
  • наприклад, плитка з сусідом E може бути NE, E або SE (якщо припустити, що вона відповідає іншим сусідам).
  • Орієнтації можуть обертатися навколо, тобто N -> NW і NW -> N.

Для ілюстрації дійсна наступна карта:

NW  N NE NE NE NE NE NE 
 N NE NE NE NE NE NE  E 
NE NE NE NE NE NE  E SE 
 E NE NE NE NE  E SE  S 
SE  E  E  E  E SE  S SE 
 S SE SE SE SE  S SE  E 
SW  S  S  S  S SE  E NE 
SW SW  S  S SE  E NE  N 

Карти повинні бути унікальними , не створювати однакову карту для різних даних.

  • Введення - це ціле число, що відповідає дням між вашим прогнозом (наприклад, 1 - завтрашній прогноз, 365 - рік).
  • Вихід - карта як зображення.
  • Вихід повинен бути відтворюваним, той самий вхід завжди даватиме однаковий вихід
  • Ви повинні дати унікальні карти принаймні 8 років - тобто немає однакового виводу на будь-який вхід між 1 і 2920 (я ігнорую високосні роки).
  • Немає визначеного виходу для жодного входу, що перевищує 2920.

Виграш подання створить дійсні карти (до 2920 дня) з найменшими байтами вихідного коду.


Який максимальний вхід потрібно обробити? Чи є якесь обмеження, наприклад, прогнози двох послідовних способів, що мають також відрізнятися лише максимальною сумою?
Інго Бюрк

Максимальний вхід, який потрібно обробити, - 2920 . Не існує обмежень для послідовних прогнозів (крім того, що вони повинні бути унікальними)
jsh

О, вибачте, я, мабуть, не помітив останню точку кулі. :)
Ingo Bürk

8
Трохи не в темі: Щойно показав це другові, який є синоптиком, і він сказав мені, що деякі з цих погодних програм, які ти можеш отримати, не набагато кращі, ніж те, що ми робимо тут, оскільки вони, очевидно, просто беруть дані про погоду великі аеропорти та інтерполюють їх, частіше за все ці інтерполяції просто смокчуть.
flawr

2
"Прийшов новий суперкомп'ютер, що прогнозує погоду, і він не працює". Подайте його до Міжнародного журналу кліматичної науки. Це буде парно за курс. : P
COTO

Відповіді:


4

BBC Basic, 83 символи ASCII, розмір файлів 72 з маркером

Завантажте емулятор за адресою http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

  INPUTn:VDU23,48,516;543;4;0;23,49,783;5,9;0;0:WIDTH8FORi=1TO64PRINT;1ANDn;:n/=2NEXT

Це в основному портрет концепції Мартіна, але реалізація в базі BBC дуже відрізняється. Я перепрограмую шрифт для чисел, 0а 1потім виводять двійкові цифри nу зворотному порядку.

Код без вольфів знаходиться нижче. На базі BBC ви можете друкувати окремі символи ASCII за допомогою VDUкоманди, але мова має ряд машино-специфічних кодів, схожих на послідовності виходу, але починаючи з недрукованих символів. Для перепрограмування шрифту ми починаємо з ASCII 23. Зазвичай приймаються 8-бітові значення, але якщо ви використовуєте крапку з комою, як роздільник, а не через коми, для 16-бітових маленьких значень ендіака (як це використовується у версії для гольфу).

  INPUTn
  VDU23,48,4,2,31,2,4,0,0,0         :REM redefine font for "0" as an east facing arrow, with an 8x8 bitmap
  VDU23,49,15,3,5,9,0,0,0,0         :REM redefine font for "1" as a northeast facing arrow, with an 8x8 bitmap
  WIDTH8                            :REM set print width to 8 characters
  FORi=1TO64PRINT;1ANDn;:n/=2:NEXT  :REM print the binary digits of n in reverse order from least significant to most significant.

Вихідні дані

Для чисел від 0 до 7. Зауважте, що шрифт не скидається в кінці програми, отже, цифри 0 і 1 з'являються у вигляді стрілок у перших двох прикладах. введіть тут опис зображення


Хороша ідея! :) Але плитки 15х15?
Мартін Ендер

@ MartinBüttner basic BBC дозволяє перевизначити шрифт у сітці 8х8. Щоб число було невеликим, я зробив найменшу впізнавану східну стрілку (5х5 затиснув у верхній правий кут сітки) і зробив найбільш схожу на північно-східну стрілку. У екрані, що використовується тут, визначення містить відповідність 1: 1 з пікселями (і залишає достатній проміжок між рядками), але я подвоїв розмір сітки в Windows Paint, щоб отримати зображення кращого розміру в SE. Деякі з інших режимів екрана в базовому режимі BBC мають більше 1 пікселя на елемент сітки, а визначені користувачем символи помітно більш зернисті, ніж звичайний шрифт.
Рівень Рівер Сент

23

Матлаб (182 *)

Передбачається, що вхід зберігається в n. Курка, дивлячись на алгоритм, не впевнена, що результати будуть унікальними, але я перевірив, наскільки n=1 upto 3000вони унікальні та відповідають правилам. В основному я просто використовую складні числа одиничного кола і 'згладжую' їх conv2 гауссовим фільтром. Після цього вони «округляються» до 8 можливих напрямків.

* Я не знаю, як масштабувати вихід на певну кількість пікселів, так що це потрібно зробити вручну = /

EDIT: Я щойно виявив, що є випадки, коли моя програма перевірки не розпізнавала неправильні рішення (зміни більш ніж на 1 крок), але я намагаюся знайти інше рішення.

Вхід:

n = 1

Код:

rand('seed',0);
for x=1:n
    b = exp(1i*rand(8)*2*pi);
end
for k=1:12
    b = conv2(b,[1,2,1]'*[1,2,1],'same');b=b./abs(b);
end
c = exp(1i*round(angle(b)*4/pi)*pi/4)/3;
quiver(real(c),imag(c));

векторного поля


Що ви маєте на увазі під "масштабуванням виводу на певну кількість пікселів", масштабуванням стрілок чи зображення?
krs013,

@ krs013 Я маю на увазі масштабування всього зображення, я ще не дізнався, як це зробити так, щоб воно було, наприклад, шириною рівно 8 * 16 пікселів.
недолік

15

Математика, 116 115 байт

f@n_:=Graphics[Array[(d=n~BitGet~#;Arrow@{1+{w=15#~Mod~8+6.5d,h=15Floor[#/8]},14+{w-13d,h}})&,64,0],ImageSize->120]

Я гадаю, хороший кінь ніколи не стрибає вище, ніж повинен. 2920 різних сіток дуже легко досягти, використовуючи лише два напрямки (я використовую Nі NE), що робить задоволення правилом безперервності тривіальним. Я просто вибираю між N та NE на основі бітів n, тому це фактично створить 2 64 різних вітрових карти.

Ось перші десять карт:

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

PS: Моя первісна ідея полягала в тому, щоб перерахувати всі 8 4 комбінації для 4 кутів та "лінійно" інтерполювати решту сітки. Це, мабуть, призвело б до приємніших карт, але все-таки це гольф з кодом, тому я пішов із тим, що відповідає мінімальним вимогам.


Я повинен був би просив 2 ^ 64 + 1 сітки. :)
jsh

@jsh У мене було 8 варіантів для двох сусідніх напрямків. Це зробило б код дещо довше, але все-таки це було б так само просто і дозволило б отримати 2 ^ 67 унікальних сіток. Але не хвилюйтеся, я думаю, що це все-таки приємний гольф-код - робити графічний вихід гольфу важко (через необхідну об'єктивність), і я думаю, що ви зробили з ним досить хорошу роботу.
Мартін Ендер

Мені подобається ідея інтерполяції, але як би ви інтерполювали, коли кожен з чотирьох кутів би вказував на центр?
flawr

4
@ MartinBüttner: Хоча це технічно відповідає специфікації, це, здається, суперечить духу виклику, який полягає у тому, щоб зробити карту правдоподібною. Просто спостереження.
COTO

2
@COTO Дуже вірно, але це також код гольфу, а не змагання за популярність, і "правдоподібність" не є об'єктивним критерієм дійсності.
Мартін Ендер

5

PHP 5,4, 549 байт

Дещо заважає потреба визначити стрілки як графічні, ось мій PHP-код:

<? $i=$argv[1];$p="R0lGODdhBQAFAIAAAP///wAAACwAAAAABQAFAAAC";$a=[$p."BwRiicGsDwoAOw",$p."CEQeoLfmlhQoADs",$p."CARiF8hnmGABADs",$p."CIwDBouYvGIoADs",$p."BwRil8Gs+QoAOw",$p."CIQRYcqrnkABADs",$p."CARihscYn1YBADs",$p."CAx+Bmq6HWIBADs"];$c=[$i&7,$i>>3&7,$i>>6&7,$i>>9];$m=imagecreate(120,120);imagecolorallocate($m,255,255,255);foreach($a as$_)$z[]=imagecreatefromstring(base64_decode($_));for($y=0;$y<8;$y++)for($x=0;$x<8;$x++)imagecopy($m,$z[($c[0]*(7-$x)*(7-$y)+$c[1]*$x*(7-$y)+$c[2]*(7-$x)*$y+$c[3]*$x*$y)/49%8],$x*15+5,$y*15+5,0,0,5,5);imagepng($m);

Аргумент бере з командного рядка, наприклад:

php windmap.php 123

Це рішення використовуватиме введення як визначення чотирьох кутів. Решта карти буде плавно інтерпольована між значеннями. Він визначив результати для всіх значень від 0 до 4095, загальна сума ~ 11,25 років підробленого прогнозу, що повинно мати більше ніж достатньо часу для виправлення програмного забезпечення погоди!

Ось GIF всіх результатів:

Гаряче повітря!

І ZIP, який містить кожну карту, можна завантажити тут

(Невелика примітка. Нещодавно мій домен минув, оскільки я не звертав уваги. Я оновив його, але наведене вище зображення та посилання можуть не працювати, поки оновлення DNS не буде)

Недосвідчений:

<?php
$input = $argv[1];
$prefix = "R0lGODdhBQAFAIAAAP///wAAACwAAAAABQAFAAAC";
$arrows = [
    $prefix."BwRiicGsDwoAOw", // E
    $prefix."CEQeoLfmlhQoADs", // NE
    $prefix."CARiF8hnmGABADs", // N
    $prefix."CIwDBouYvGIoADs", // NW
    $prefix."BwRil8Gs+QoAOw", // W
    $prefix."CIQRYcqrnkABADs", // SW
    $prefix."CARihscYn1YBADs", // S
    $prefix."CAx+Bmq6HWIBADs", // SE
];
$points = [
    $input & 7,
    $input >> 3 & 7,
    $input >> 6 & 7,
    $input >> 9 // input beyond 0o7777 (4095) will be undefined due to lack of & 7 here
];
$img = imagecreate(120,120);
imagecolorallocate($img,255,255,255);
$arrowimgs = [];
foreach($arrows as $src) {
    $arrowimgs[] = imagecreatefromstring(base64_decode($src));
}
for($y=0; $y<8; $y++) {
    for($x=0; $x<8; $x++) {
        $point = (
              $points[0] * (7-$x)/7 * (7-$y)/7
            + $points[1] *   $x  /7 * (7-$y)/7
            + $points[2] * (7-$x)/7 *   $y  /7
            + $points[3] *   $x  /7 *   $y  /7
        ) % 8;
        imagecopy($img,$arrowimgs[$point],$x*15+5,$y*15+5,0,0,5,5);
    }
}
imagepng($img,"out.png");

Як працює інтерполяція?
недолік

@flawr Це наближає відстань до кожного кута і використовує його як вагу для того, наскільки значення цього кута має впливати на значення поточної точки.
Niet the Dark Absol

Але в цьому випадку кожна стрілка повинна вказувати на середину в кадрі 1647? tinyurl.com/o7z9grl
flawr

1
@flawr Подивіться на крайній лівий стовпець, щоб побачити, як це "інтерполяція" від 7 (SE) до 1 (NE), переглянувши всі значення 6, 5, 4, 3, 2 ... на відміну від коротших "7, 0, 1 ", що ви можете очікувати. Алгоритм недостатньо складний для інтерполяції з таким обертанням.
Niet the Dark Absol

Ах, як ти це вирішив! Це справді приємно, оскільки інтерпозація з "7,0,1" призвела б до невірного поля стрілки =) +1 для графіки стрілки!
недолік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.