伪造预测


15

新的天气预报超级计算机已经到货,并且不起作用。

同时,您的老板希望您通过伪造每日风向图来花一些时间来购买技术人员。

您的任务是绘制代表风向的箭头网格。

网格为:

  • 由15像素的正方形瓷砖组成
  • 8瓦乘8瓦
  • 总计120像素见方
  • 000背景

每个网格图块都有8个可能的方向,代表风向:

  1. 东北
  2. 东南
  3. 西南
  4. 西方
  5. 西北

必须将其描述如下:

N ñ NE 东北 E Ë SE 东南 S 小号 SW 西南 W w ^ NW西北

地图必须逐渐变化,以便可信。

这意味着每个图块可能仅与它的邻居相差一个步骤。特别:

  • 一个图块只能与四个相邻图块中的每一个相差一个增量或减量。(或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之间的任何输入都没有相同的输出(我忽略了leap年)。
  • 任何大于2920的输入都没有定义的输出。

获胜的提交将生成有效的地图(到2920天),并且源代码的字节数最少。


需要处理的最大输入量是多少?例如,两个连续方式的预测也必须相差最大吗?
IngoBürk2014年

需要处理的最大输入为2920。对连续的预报没有限制(除了它们必须是唯一的)
jsh 2014年

哦,对不起,我一定忽略了最后一点。:)
IngoBürk2014年

8
稍微偏离主题:刚刚向一位天气预报员的朋友展示了此内容,他告诉我,您可以获得的某些天气应用程序并没有比我们在这里做的要好得多,因为它们显然只是从中获取免费的天气数据。大型机场并对其进行插值,而这些插值往往不是那么容易。
瑕疵的

2
“新的天气预报超级计算机已经到来,并且不起作用。” 提交给国际气候科学杂志。这将是课程的标准。:P
COTO 2014年

Answers:


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

这基本上是Martin概念的移植,但是BBC基本版的实现却大不相同。我为数字重新编程了字体01然后n以相反的顺序输出二进制数字。

下面是非高尔夫代码。在BBC basic中,您可以使用VDU命令来打印单个ASCII字符,但是该语言具有一系列机器特定的代码,类似于转义序列,但以不可打印的字符开头。为了重新编程字体,我们从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在前两个示例中显示为箭头。 在此处输入图片说明


好主意!:)但是瓦片是15x15吗?
Martin Ender 2014年

@MartinBüttnerBBC基本版允许您在8x8网格上重新定义字体。为了使数字保持较小,我使用了可识别的最小东箭头(将5x5压缩到网格的右上角),并制作了最相似的东北箭头。在此处使用的屏幕模式下,定义与像素具有1:1对应关系(并在行之间留出足够的间隙),但是我将Windows Paint中的网格大小加倍,以在SE上获得更好的大小图像。BBC基本版中的某些其他屏幕模式每个网格元素具有1个以上的像素,并且用户定义的字符比常规字体明显更粗糙。
级圣河

23

Matlab(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 2014年

@ krs013我的意思是缩放整个图像,但我还没有找到如何做到这一点的功能,例如它的宽度恰好是8 * 16像素。
瑕疵的

15

Mathematica, 116115字节

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个不同的网格(我正在使用NNE),这使得满足连续性规则变得微不足道。我只是基于的位在N和NE之间进行选择n,因此实际上会产生2 64个不同的风向图。

以下是前十张地图:

在此处输入图片说明

PS:我最初的想法是枚举4个角的所有8 4个组合,然后“线性”插值其余的网格。那可能会生成更好的地图,但这毕竟是代码高尔夫,所以我选择了满足最低要求的产品。


我应该要求2 ^ 64 + 1网格。:)
jsh 2014年

@jsh我有两个相邻方向的8个选择。这样做可以使代码更长一些,但同样也很容易,并且可以使用2 ^ 67个唯一的网格。但是不用担心,我认为这仍然是一个不错的代码高尔夫-由于要求的客观性,很难进行图形输出高尔夫(高尔夫),而且我认为您在此方面做得很好。
Martin Ender 2014年

我喜欢插值的概念,但是当四个角中的每一个指向中心时如何进行插值?
瑕疵的

4
@MartinBüttner:尽管这在技术上符合规范,但这似乎与挑战精神背道而驰,即使地图可信。只是一个观察。
COTO 2014年

2
@COTO非常正确,但是它也编码高尔夫,而不是普及竞赛,“可信度”不是客观的有效标准。
Martin Ender 2014年

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 2014年

但是在这种情况下,每个箭头都应指向框架1647的中间?tinyurl.com/o7z9grl
瑕疵者

1
@flawr在最左边的列中向下查看,以了解它是如何通过遍历所有值6、5、4、3、2 ...(而不是较短的“ 7,您可能期望的0、1“。该算法不够复杂,无法像这样进行旋转插值。
Niet the Dark Absol 2014年

多数民众赞成在解决您的问题!这真的很好,因为插入'7,0,1'会导致箭头图形的箭头字段=)+1无效!
瑕疵的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.