使用列表对列表进行分区
Partitioning a List using a List
我正在做一个项目,该项目要求我使用列表对列表进行分区。我创建了一个在某些情况下有效但并非在所有情况下都有效的解决方案。有谁能帮我解决逻辑问题吗?
有两个列表。每个列表的总和将始终相等。第一个列表(即partitionBy列表)用于对第二个列表(即inputList)进行分区。
这是一个简化的例子:
列表 A {3, 2, 4}
列表 B {2, 1, 1, 1, 3, 1}
列表A的第一项是3。列表B的第一项和第二项之和= 3(即2 + 1)。为这些项目创建一个列表
列表A的第二项是2。列表B的第三项和第四项之和=2(即1+1)。为这些项目创建一个列表
等...
理想的结果是:{{2, 1}, {1, 1}, {3, 1}}
代码目前在 AppleScript 中,但如果有帮助,我很乐意将其翻译成 JavaScript。
这是带示例的代码:
--Example 1 works as expected
set partitionBy1 to {4, 1, 9, 6, 2, 2} -- list to partition by
set inputList1 to {1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1} -- list to partition
-- required output: {{1, 1, 1, 1}, {1}, {2, 2, 2, 3}, {3, 3}, {1, 1}, {1, 1}}
-- actual output: {{1, 1, 1, 1}, {1}, {2, 2, 2, 3}, {3, 3}, {1, 1}, {1, 1}}
--Example 2 works as expected
set partitionBy2 to {4, 2, 8, 6, 2, 2}
set inputList2 to {1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1}
-- required output: {{1, 1, 1, 1}, {1, 1}, {1, 2, 2, 3}, {3, 3}, {1, 1}, {1, 1}}
-- actual output: {{1, 1, 1, 1}, {1, 1}, {1, 2, 2, 3}, {3, 3}, {1, 1}, {1, 1}}
--Example 3 does not work as expected
set partitionBy3 to {4, 1, 9, 1, 3, 6, 2, 2}
set inputList3 to {1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 3, 3, 1, 1, 1, 1}
-- required output: {{1, 1, 1, 1}, {1}, {2, 2, 2, 3}, {1}, {3}, {3, 3}, {1, 1}, {1, 1}}
-- actual output: {{1, 1, 1, 1}, {1}, {2, 2, 2, 3}, {3}, {3}, {3, 3}, {1, 1}, {1, 1}}
partitionList(inputList3, partitionBy3)
on partitionList(inputList, partitionBy)
set partitionedList to {}
repeat with i from 1 to (count partitionBy)
set partitionNumber to item i of partitionBy
set runningTotal to 0
set intermediateList to {}
repeat with j from 1 to ((count inputList) - 1)
set inputNumber to item j of inputList
set runningTotal to runningTotal + inputNumber
if runningTotal = partitionNumber then
set end of partitionedList to (intermediateList & inputNumber)
set inputList to items (j + 1) thru -1 of inputList
exit repeat
else if runningTotal > partitionNumber then
set item j of inputList to (inputNumber - 1)
set inputList to (inputNumber - 1) & inputList
set end of partitionedList to (intermediateList & (inputNumber - 1))
set inputList to items (j + 1) thru -1 of inputList
exit repeat
else
set end of intermediateList to inputNumber
end if
end repeat
end repeat
set end of partitionedList to intermediateList & item -1 of inputList
return partitionedList
end partitionList
问题是j
的线性递增。
在 runningTotal > partitionNumber
的情况下,您必须将差异(或余数)分配给 inputNumber
并在不递增 j
.
的情况下评估下一个分区
我将 repeat with
替换为 repeat while
,添加了一个 overflow
变量以指示 runningTotal
大于 partitionNumber
并声明了 j
作为具有完全控制权的局部变量。
on partitionList(inputList, partitionBy)
set partitionedList to {}
set j to 1
set overflow to false
repeat with i from 1 to (count partitionBy)
set partitionNumber to item i of partitionBy
set runningTotal to 0
set intermediateList to {}
repeat while j < (count inputList)
if overflow then
set overflow to false
else
set inputNumber to item j of inputList
end if
set runningTotal to runningTotal + inputNumber
if runningTotal = partitionNumber then
set end of partitionedList to (intermediateList & inputNumber)
set j to j + 1
exit repeat
else if runningTotal > partitionNumber then
set end of partitionedList to {partitionNumber}
set overflow to true
set inputNumber to runningTotal - partitionNumber
exit repeat
else
set end of intermediateList to inputNumber
set j to j + 1
end if
end repeat
end repeat
set end of partitionedList to intermediateList & item -1 of inputList
return partitionedList
end partitionList
我正在做一个项目,该项目要求我使用列表对列表进行分区。我创建了一个在某些情况下有效但并非在所有情况下都有效的解决方案。有谁能帮我解决逻辑问题吗?
有两个列表。每个列表的总和将始终相等。第一个列表(即partitionBy列表)用于对第二个列表(即inputList)进行分区。
这是一个简化的例子:
列表 A {3, 2, 4} 列表 B {2, 1, 1, 1, 3, 1}
列表A的第一项是3。列表B的第一项和第二项之和= 3(即2 + 1)。为这些项目创建一个列表
列表A的第二项是2。列表B的第三项和第四项之和=2(即1+1)。为这些项目创建一个列表
等...
理想的结果是:{{2, 1}, {1, 1}, {3, 1}}
代码目前在 AppleScript 中,但如果有帮助,我很乐意将其翻译成 JavaScript。
这是带示例的代码:
--Example 1 works as expected
set partitionBy1 to {4, 1, 9, 6, 2, 2} -- list to partition by
set inputList1 to {1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1} -- list to partition
-- required output: {{1, 1, 1, 1}, {1}, {2, 2, 2, 3}, {3, 3}, {1, 1}, {1, 1}}
-- actual output: {{1, 1, 1, 1}, {1}, {2, 2, 2, 3}, {3, 3}, {1, 1}, {1, 1}}
--Example 2 works as expected
set partitionBy2 to {4, 2, 8, 6, 2, 2}
set inputList2 to {1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 1, 1, 1}
-- required output: {{1, 1, 1, 1}, {1, 1}, {1, 2, 2, 3}, {3, 3}, {1, 1}, {1, 1}}
-- actual output: {{1, 1, 1, 1}, {1, 1}, {1, 2, 2, 3}, {3, 3}, {1, 1}, {1, 1}}
--Example 3 does not work as expected
set partitionBy3 to {4, 1, 9, 1, 3, 6, 2, 2}
set inputList3 to {1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 3, 3, 1, 1, 1, 1}
-- required output: {{1, 1, 1, 1}, {1}, {2, 2, 2, 3}, {1}, {3}, {3, 3}, {1, 1}, {1, 1}}
-- actual output: {{1, 1, 1, 1}, {1}, {2, 2, 2, 3}, {3}, {3}, {3, 3}, {1, 1}, {1, 1}}
partitionList(inputList3, partitionBy3)
on partitionList(inputList, partitionBy)
set partitionedList to {}
repeat with i from 1 to (count partitionBy)
set partitionNumber to item i of partitionBy
set runningTotal to 0
set intermediateList to {}
repeat with j from 1 to ((count inputList) - 1)
set inputNumber to item j of inputList
set runningTotal to runningTotal + inputNumber
if runningTotal = partitionNumber then
set end of partitionedList to (intermediateList & inputNumber)
set inputList to items (j + 1) thru -1 of inputList
exit repeat
else if runningTotal > partitionNumber then
set item j of inputList to (inputNumber - 1)
set inputList to (inputNumber - 1) & inputList
set end of partitionedList to (intermediateList & (inputNumber - 1))
set inputList to items (j + 1) thru -1 of inputList
exit repeat
else
set end of intermediateList to inputNumber
end if
end repeat
end repeat
set end of partitionedList to intermediateList & item -1 of inputList
return partitionedList
end partitionList
问题是j
的线性递增。
在 runningTotal > partitionNumber
的情况下,您必须将差异(或余数)分配给 inputNumber
并在不递增 j
.
我将 repeat with
替换为 repeat while
,添加了一个 overflow
变量以指示 runningTotal
大于 partitionNumber
并声明了 j
作为具有完全控制权的局部变量。
on partitionList(inputList, partitionBy)
set partitionedList to {}
set j to 1
set overflow to false
repeat with i from 1 to (count partitionBy)
set partitionNumber to item i of partitionBy
set runningTotal to 0
set intermediateList to {}
repeat while j < (count inputList)
if overflow then
set overflow to false
else
set inputNumber to item j of inputList
end if
set runningTotal to runningTotal + inputNumber
if runningTotal = partitionNumber then
set end of partitionedList to (intermediateList & inputNumber)
set j to j + 1
exit repeat
else if runningTotal > partitionNumber then
set end of partitionedList to {partitionNumber}
set overflow to true
set inputNumber to runningTotal - partitionNumber
exit repeat
else
set end of intermediateList to inputNumber
set j to j + 1
end if
end repeat
end repeat
set end of partitionedList to intermediateList & item -1 of inputList
return partitionedList
end partitionList