将阵列和程序一分为二


10

介绍

您的任务是编写一个程序,将矩形整数数组平均分成两半(无论出于何种原因)。该任务需要大量计算,但是幸运的是您有一台双核计算机来执行计算。为了最大限度地提高并行性的好处,您决定将程序平均分成两半,并让每个内核独立地运行一个部分。

输入输出

您的输入是大小为1×1的非负整数的矩形2D数组,采用任何合理格式。甲分裂这种阵列的被分割的每个水平行所获得成前缀和后缀(其中任一个可能是空的)。为了使拆分有效,必须在相同索引或相邻索引处拆分两个相邻行。例如,考虑数组

2 4 5 5 6 3
9 7 1 7 7 0
0 0 3 6 7 8
1 2 4 7 6 1
6 6 8 2 0 0

这是有效的拆分:

 2;4 5 5 6 3
;9 7 1 7 7 0
;0 0 3 6 7 8
 1;2 4 7 6 1
 6 6;8 2 0 0

这也是有效的拆分方法:

2 4 5 5 6 3;
9 7 1 7 7;0
0 0 3 6 7;8
1 2 4 7;6 1
6 6 8;2 0 0

这不是有效的拆分:

2 4;5 5 6 3
9 7 1;7 7 0
0;0 3 6 7 8
1 2;4 7 6 1
6 6;8 2 0 0

您的输出应为的最小值

abs(sum_of_prefixes - sum_of_suffixes)

输入的所有有效分割。

规则和计分

您应使用相同的语言编写两个程序(完整程序或函数),它们之间不得有任何共享代码。我们称它们为P1P2。程序P1接受输入阵列,并将其输出的东西。程序P2将此作为输入,并为输入数组输出上述任务的答案。

您的分数是P1P2最大字节数,分数越低越好。

一些说明:

  • 您可以编写两个完整的程序,一个功能和一个完整的程序或两个功能。
  • 在两个完整程序的情况下,P1的全部输出作为输入送入P2,就像在Unix管道中一样P1 | P2。如果从两个单独的源文件进行编译/解释,则程序必须正确运行。
  • 如果任何一个程序都是函数,则通过添加必要的样板代码将其转换为完整程序,并将上述规则应用于该程序。特别是,两个函数不能使用共享的辅助函数,共享的导入语句或共享的全局变量。

测试用例

[[1]] -> 1
[[4,5],[8,3]] -> 4
[[8],[11],[8],[10],[4]] -> 1
[[5,7,0,9,11,2,1]] -> 7
[[146,194,71,49],[233,163,172,21],[121,173,14,302],[259,169,26,5],[164,30,108,37],[88,55,15,2]] -> 3
[[138,2,37,2],[168,382,33,77],[31,199,7,15],[192,113,129,15],[172,88,78,169],[28,6,97,197]] -> 7
[[34,173,9,39,91],[169,23,56,74,5],[40,153,80,60,28],[8,34,102,60,32],[103,88,277,4,2]] -> 0
[[65,124,184,141],[71,235,82,51],[78,1,151,201],[12,24,32,278],[38,13,10,128],[9,174,237,113]] -> 2
[[164,187,17,0,277],[108,96,121,263,211],[166,6,57,49,73],[90,186,26,82,138],[173,60,171,265,96]] -> 8

一会儿,我认为这是一个多线程问题。我一直期待更多这样的事情。
亚当

Answers:


2

Haskell,102字节

功能1(102字节):

l=length
[]#i=[[]]
(r:s)#i=id=<<[(splitAt j r:)<$>s#j|j<-[i-1..i+1],j>=0,j<l r]
f r=(r#)=<<[0..l$r!!0]

功能2(90字节):

g::[[([Int],[Int])]]->Int 
g a=minimum$map(\(x,y)->abs$sum(sum<$>x)-sum(sum<$>y))$unzip<$>a

F1缺少使它成为完整程序的样板,包括要检查的硬编码整数数组:

main = print $ f [[164,187,17,0,277],[108,96,121,263,211],[166,6,57,49,73],[90,186,26,82,138],[173,60,171,265,96]]

对于F2:

main = print . g . read =<< getContents

现在您可以调用runhaskell f1.hs | runhaskell f2.hs哪些输出8

工作原理:f获取整数列表。

f r = (r#)=<<[0..l$r!!0]          -- for each index [0 .. length r] call # with
                                  -- the first parameter being r and
                                  -- collect the results in a single list

[]#i=[[]]                         -- base case. If the list of lists is empty, stop
(r:s)#i                           -- else let r be the first list, s all others
           j<-[i-1..i+1],         -- foreach possible index j for the next line
                 j>=0,j<l r       --    (skipping out of range indices)
     (splitAt j r:)<$>            -- split the current line at j into a pair of
                                  -- lists and prepend it to every element of
                      s#j         -- a recursive call with s and j
id=<<                             -- flatten into a single list

现在我们有了所有可能分割的列表,例如第一个分割和中间的一个随机分割

[([],[164,187,17,0,277]),                  [([164,187],[17,0,277]),
 ([],[108,96,121,263,211]),                 ([108,96],[121,263,211]),
 ([],[166,6,57,49,73]),                     ([166],[6,57,49,73]),
 ([],[90,186,26,82,138]),                   ([90,186],[26,82,138]),
 ([],[173,60,171,265,96])]                  ([173,60,171],[265,96])]

函数g采用这样的列表,

                    unzip<$>a       -- turn every pair of lists into a list of pairs
  map(\(x,y)->                      -- foreach such pair     
      abs$sum(sum<$>x)-sum(sum<$>y) -- calculate the score
minimum                             -- and find the minimum

注意:第二功能可以打更多一点,但不会改变得分。

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.