Поддельный прогноз


15

Новый суперкомпьютер для прогнозирования погоды прибыл, и он не работает.

Тем временем ваш начальник хочет, чтобы вы некоторое время покупали техников, подделывая ежедневные карты ветра.

Ваша задача - нарисовать сетку стрелок, обозначающих направление ветра.

Сетка это:

  • состоит из 15px квадратных плиток
  • 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 NWNW

Карты должны меняться постепенно , чтобы быть правдоподобными.

Это означает, что каждый тайл может отличаться от соседа только на один шаг. В частности:

  • Плитка может отличаться только на один шаг или приращение от каждой из 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

Ой, извини, я, должно быть, упустил из виду последний пункт. :)
Инго Бюрк

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 basic очень отличается. Я перепрограммирую шрифт для чисел 0и 1затем выводю двоичные цифры nв обратном порядке.

Ungolfed код ниже. В BBC basic вы можете печатать отдельные символы ASCII, используя VDUкоманду, но язык имеет ряд машинно-специфических кодов, похожих на escape-последовательности, но начинающихся с непечатаемых символов. Для перепрограммирования шрифта мы начинаем с 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 BBC basic позволяет переопределить шрифт на сетке 8x8. Чтобы цифры были маленькими, я сделал наименьшую узнаваемую стрелку восток (5x5, втиснутую в верхний правый угол сетки) и сделал самую похожую стрелку северо-востока. В используемом здесь режиме экрана определение имеет соотношение 1: 1 с пикселями (и оставляет достаточно промежутков между строками), но я удвоил размер сетки в Windows Paint, чтобы получить лучшее изображение размера на SE. Некоторые другие режимы экрана в BBC basic имеют более 1 пикселя на элемент сетки, а определяемые пользователем символы заметно более зернисты, чем обычный шрифт.
Уровень Река St

23

Матлаб (182 *)

Предполагается, что вход хранится в n. Что касается алгоритма, то он не уверен, что результаты будут уникальными, но я проверил, n=1 upto 3000что они уникальны и соответствуют правилам. Я просто использую комплексные числа единичного круга и сглаживаю их с помощью conv2 с помощью гауссовского фильтра. После этого они округляются до 8 возможных направлений.

* Я не знаю, как масштабировать вывод до определенного количества пикселей, так что это должно быть сделано вручную = /

РЕДАКТИРОВАТЬ: Я только что обнаружил, что есть случаи, когда моя программа проверки не распознала неправильные решения (изменения более чем на 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 пикселей.
Flawr

15

Mathematica, 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)

Unsquishified:

<?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

@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 для графики стрелки!
Flawr
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.