The goal of this challenge is to complete a list of consecutive nested header numbers when given a start and an end. When given 1.1.1
and 1.1.5
you should generate 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5
Specific Rules
- Your entry must take in a
start
,end
, and multiple optionalrange
parameters. Parameters can be taken form STDIN (or nearest equivalent) or a file. - Your entry may assume valid input
- Input will be of the following format:
start
andend
will be strings of.
delimited integers of the same lengthstart
andend
will have three segments; (1) set values, (2) iterator, (3) trailing values.- The iterator is the first value which differs between
start
andend
. - The set values are the values before the iterator. These values never change
- The trailing values are the values after the iterator. These values iterate up as determined by the
range
parameter(s). All trailing values instart
andend
will be1
.
- The iterator is the first value which differs between
range
will be a list of integers or strings (depending on which you prefer) with a length corresponding to the number of trailing values. When there are no trailing values,range
is not specified. The value ofrange
corresponding to each trailing value determines the inclusive upper bound which that entry iterates to.
- Output will be to STDOUT (or closest alternative) and will show each value separated by at least one delimiter. Delimiter can by any character or string of characters, but it must be consistent. Output must be sorted correctly
Examples
start = '1.1.5.1', end = '1.1.6.1', range = [5]
Output: 1.1.5.1, 1.1.5.2, 1.1.5.3, 1.1.5.4, 1.1.5.5, 1.1.6.1
^
previous value is iterated
only when iterating value
limit set by range
start = '1.1.5.1', end = '1.1.7.1', range = [5]
Output: 1.1.5.1, 1.1.5.2, 1.1.5.3, 1.1.5.4, 1.1.5.5, 1.1.6.1,
1.1.6.2, 1.1.6.3, 1.1.6.4, 1.1.6.5, 1.1.7.1
start = '1.5.1.1', end = '1.6.1.1', range = [5,2]
Output: 1.5.1.1, 1.5.1.2, 1.5.2.1, 1.5.2.2, 1.5.3.1, 1.5.3.2,
1.5.4.1, 1.5.4.2, 1.5.5.1, 1.5.5.2, 1.6.1.1
This is code golf so shortest code by bytes wins. Standard loopholes apply.
Bonuses
- Allow trailing values to be values other than
1
inend
parameter - 12.5% off - Handle incorrect number of values in
range
parameter - 12.5% off - Handle
end
less thanstart
by producing list in reverse - 50% off
Bonuses are calculated off of the original byte count; a 100 byte answer which receives all bonuses will have a final score of 100 bytes - 100*(0.125+0.125+0.5) = 25 bytes
2 Answers 2
Haskell, (削除) 201 (削除ここまで) (削除) 194 (削除ここまで) 188*0.25 = 47 bytes
import Data.Lists
l=length
p x=read<$>splitOn"."x
(s#e)r=intercalate".".map show<$>(fst$span(<=e)$sequence$zipWith enumFromTo s$take(l e-l r)e++r)
s!e|s<e=s#e|1<2=reverse.(e#s)
(.p).(!).p
I'm going for all bonuses.
"Normal" use:
*Main> ((.p).(!).p) "1.5.1.1" "1.6.1.1" [5,2]
["1.5.1.1","1.5.1.2","1.5.2.1","1.5.2.2","1.5.3.1","1.5.3.2","1.5.4.1",
"1.5.4.2","1.5.5.1","1.5.5.2","1.6.1.1"]
Bonus 1:
*Main> ((.p).(!).p) "1.5.1.1" "1.6.4.1" [5,2]
["1.5.1.1","1.5.1.2","1.5.2.1","1.5.2.2","1.5.3.1","1.5.3.2","1.5.4.1",
"1.5.4.2","1.5.5.1","1.5.5.2","1.6.1.1","1.6.1.2","1.6.2.1","1.6.2.2",
"1.6.3.1","1.6.3.2","1.6.4.1"]
Bonus 2:
*Main> ((.p).(!).p) "1.5.1.1" "1.6.1.1" [3]
["1.5.1.1","1.5.1.2","1.5.1.3","1.6.1.1"]
Bonus 3:
*Main> ((.p).(!).p) "1.6.1.1" "1.5.1.1" [5,2]
["1.6.1.1","1.5.5.2","1.5.5.1","1.5.4.2","1.5.4.1","1.5.3.2","1.5.3.1",
"1.5.2.2","1.5.2.1","1.5.1.2","1.5.1.1"]
How it works:
Split start
and end
into lists of numbers, e.g. "1.5.1.1"
-> [1,5,1,1]
. Prepend elements from end
to range
so that the resulting list has the same length as end
, e.g. [5,2]
and "1.6.1.1"
-> [1,6,5,2]
. Zip this list and start
with the list building function enumFromTo
, e.g. [1,5,1,1]
and [1,6,5,2]
-> [[1],[5,6],[1,2,3,4,5],[1,2]]
. sequence
builds all combinations thereof, where numbers at position i are drawn from sublist i, -> [[1,5,1,1],[1,5,1,2],[1,5,2,1],[1,5,2,2],...]
. Re-insert the dots and take elements as long as the they are less or equal than end
.
PowerShell, 214 bytes, no bonuses :(
param($s,$e,$r)
$f={param($v,$w)if($w){$w[0]|%{&$f "$v.$_" $w[1..$w.Count]}}else{$v;if($v-eq$e){break}}}
$x,$y=($s-split'\.'|diff $e.split('.')).inputobject
$q=,($x..$y)
$r|%{$q+=,(1..$_)}
&$f ($s-split".$x")[0] $q
e.g.
PS C:\Scripts> .\nestedh.ps1 '1.5.1.1' '1.6.1.1' @(5,2)
1.5.1.1
1.5.1.2
1.5.2.1
1.5.2.2
1.5.3.1
1.5.3.2
1.5.4.1
1.5.4.2
1.5.5.1
1.5.5.2
1.6.1.1
It:
- Uses
-split '\.'
feeding todiff/Compare-Object
to find the two differing numbers, (this approach blocks the bonus where the tail values can change, because it changes the diff output). - Builds an array of the ranges it will need for each header position, taking from the range parameters.This leaves something like
"$q=[[5,6], [1,2,3,4,5], [1,2]]"
- Those get fed into the recursive function
$f
which takes the set values prefix and a list of sublists, adds the prefix to each number, and calls itself with that as the new prefix, and the remaining sublists - quits when it hits the
$end
string
1.1.6.1
? \$\endgroup\$1
's? Are all the numbers instart
andend
single digits, or could1.1.22.1 to 1.1.24.1
happen? \$\endgroup\$