# Bottom part of the Hourglass

## Challenge:

Input: Three integers: bottom-edge length; starting amount of grains of sand; index

Output: Output the state of the bottom part of an hourglass at the given index, based on the given bottom-edge length and amount of grains of sand.

## Challenge rules:

• We simulate the grains of sand with digits 1-9
• We put the currently remaining amount of grains of sand at the top in the middle, following by a single character of your own choice (excluding digits, whitespaces and new-lines; i.e. -) on the line below it
• When the hourglass is being filled, we fill it per row, one digit at a time
• When the sand can go either left or right, we ALWAYS go right (the same applies to balancing the remaining amount of grains of sand above the hour glass)
• When we've reached 9 it's filled, and we can't fit any more sand at that specific place in the hourglass
• The amount of grains of sand left are also always rightly aligned
• Once the bottom halve of the hourglass is completely filled, or the amounts of grains of sand left reaches 0, we can't go any further, and this would be the output for all indexes beyond this point
• Trailing and leading spaces and a single trailing or leading new-line are optional
• You are allowed to use any other character instead of a zero to fill up empty spaces of the bottom part of the hourglass (excluding digits, new-lines, or the character you've used as neck), if you choose to display them.
• The bottom-edge length will always be odd
• The bottom-edge length will be >= 3; and the amounts of grains of sand >= 0
• If you want you are also allowed to print all states up to and including the given index
• You can assume the (0-indexed) index will never be larger than the total amount of grains of sand (so when there are 100 grains of sand, index 100 is the maximum valid index-input).
• The first index (0 for 0-indexed; 1 for 1-indexed) will output an empty hourglass with the amount of grains of sand above it.

Example: Pictures (or ascii-art) say more than a thousand words, so here is an example:

Input bottom-edge length: 5
Input amount of grains of sand: 100
Instead of a current index, I display all steps here:

Output for all possible indexes with bottom-edge length 5 and amount of grains of sand 100:

 100
-
0
000
00000

99
-
0
000
00100

98
-
0
000
00110

97
-
0
000
01110

96
-
0
000
01111

95
-
0
000
11111

94
-
0
000
11211

93
-
0
000
11221

92
-
0
000
12221

91
-
0
000
12222

90
-
0
000
22222

89
-
0
000
22322

88
-
0
000
22332

87
-
0
000
23332

86
-
0
000
23333

85
-
0
000
33333

84
-
0
000
33433

83
-
0
000
33443

82
-
0
000
34443

81
-
0
000
34444

80
-
0
000
44444

79
-
0
000
44544

78
-
0
000
44554

77
-
0
000
45554

76
-
0
000
45555

75
-
0
000
55555

74
-
0
000
55655

73
-
0
000
55665

72
-
0
000
56665

71
-
0
000
56666

70
-
0
000
66666

69
-
0
000
66766

68
-
0
000
66776

67
-
0
000
67776

66
-
0
000
67777

65
-
0
000
77777

64
-
0
000
77877

63
-
0
000
77887

62
-
0
000
78887

61
-
0
000
78888

60
-
0
000
88888

59
-
0
000
88988

58
-
0
000
88998

57
-
0
000
89998

56
-
0
000
89999

55
-
0
000
99999

54
-
0
010
99999

53
-
0
011
99999

52
-
0
111
99999

51
-
0
121
99999

50
-
0
122
99999

49
0
222
99999

48
-
0
232
99999

47
-
0
233
99999

46
-
0
333
99999

45
-
0
343
99999

44
-
0
344
99999

43
-
0
444
99999

42
-
0
454
99999

41
-
0
455
99999

40
-
0
555
99999

39
-
0
565
99999

38
-
0
566
99999

37
-
0
666
99999

36
-
0
676
99999

35
-
0
677
99999

34
-
0
777
99999

33
-
0
787
99999

32
-
0
788
99999

31
-
0
888
99999

30
-
0
898
99999

29
-
0
899
99999

28
-
0
999
99999

27
-
1
999
99999

26
-
2
999
99999

25
-
3
999
99999

24
-
4
999
99999

23
-
5
999
99999

22
-
6
999
99999

21
-
7
999
99999

20
-
8
999
99999

19
-
9
999
99999


So as example:

inputs: 5,100,1
output:
99
-
0
000
00100

Same example with another valid output format:
99
~
.
...
..1..


## General rules:

• This is , so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
• Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
• Default Loopholes are forbidden.

## Test cases:

INPUTS: bottom-edge length, amount of grains of sand, index (0-indexed)

inputs: 5,100,1
output:
99
-
0
000
00100

inputs: 5,100,24
output:
76
-
0
000
45555

inputs: 5,100,100
output:
19
-
9
999
99999

inputs: 5,10,15
output:
0
-
0
000
22222

inputs: 3,30,20
output:
10
-
0
677

inputs: 3,3,0
3
-
0
000

inputs: 9,250,100
150
-
0
000
00000
2333332
999999999

inputs: 9,225,220
5
-
4
999
99999
9999999
999999999

inputs: 13,1234567890,250
1234567640
-
0
000
00000
0000000
344444443
99999999999
9999999999999

inputs: 25,25,25
0
-
0
000
00000
0000000
000000000
00000000000
0000000000000
000000000000000
00000000000000000
0000000000000000000
000000000000000000000
00000000000000000000000
1111111111111111111111111

• For 5,100,10000 why does 20+9+9+9+9+9+9+9+9+9 = 101? – Neil Jan 25 '18 at 8:57
• @Neil I'll change the rules a bit so the index can never go beyond the total sum. Probably better to understand. – Kevin Cruijssen Jan 25 '18 at 9:03
• Related – Laikoni Jan 25 '18 at 9:38
• is the first input always an odd number? – Brian H. Jan 25 '18 at 15:47
• @BrianH. "The bottom-edge length will always be odd" I realize I have a bit too much rules in this challenge, so I can understand you've read past it. :) – Kevin Cruijssen Jan 25 '18 at 16:12

# 05AB1E, 68635957 56 bytes

IÅÉÅ9[DOO²Q#ćD_Piˆëć<¸«¸ì]ćā<ΣÉ}2äćR¸ì˜è¸ì¯ìJDSOIα'-‚ì.C


Try it online!

Explanation

IÅÉÅ9
We initialize the stack with a list of list of 9's.
Each list represents a row so the length of each list is odd and the length of the last list is equal to the first input.
An input of 5 would result in [[9], [9, 9, 9], [9, 9, 9, 9, 9]]

[DOO²Q#ćD_Piˆëć<¸«¸ì]
We then iterate over these lists decrementing elements in a list until the list consists only of zeroes, then moving on to the next. We stop when the total sum equals the second input.

[     #              ]   # loop until
DOO                     # the sum of the list of lists
²Q                   # equals the second input
ć                # extract the first list
D_Pi            # if the product of the logical negation of all elements is true
ˆ           # add the list to the global list
ë          # else
ć<        # extract the head and decrement it
¸«      # append it to the list
¸ì    # and prepend the list to the list of lists


Now we need to unsort the final list simulating removing elements from alternating sides instead of left-to-right as we have been doing.

ć                   # extract the row we need to sort
ā<                 # push a list of indices of the elements [0 ... len(list)-1]
ΣÉ}              # sort it by even-ness
2äćR¸ì˜       # reverse the run of even numbers
# the resulting list will have 0 in the middle,
odd number increasing to the right and
even numbers increasing to the left
è      # index into our final row with this
¸ì¯ì  # reattach all the rows to eachother


Now we format the output correctly

J              # join list of lists to list of strings
DSOIα         # calculate the absolute difference of sum of our triangle and the 3rd input
'-‚ì     # pair it with the string "-" and append to the list of rows
.C   # join by newlines and center each row

• Really? It was this complicated? – Magic Octopus Urn Jan 29 '18 at 14:43
• @MagicOctopusUrn: You are very welcome to outgolf me :) Some things about this method became a bit messy due to language quirks that I haven't found a better way around. Maybe there's a better way altogether? Maybe something more mathematical? – Emigna Jan 29 '18 at 18:34
• I was thinking about using binary numbers somehow... didn't think it out fully, didn't have a spare hour. – Magic Octopus Urn Jan 29 '18 at 18:58
• It has been awhile since I've tried to outgolf one of your solutions that's more than 20 bytes. Bit ashamed to admit it, but when I see your answers I usually don't waste the time trying to find improvements anymore; because usually I am unable to find any hah! – Magic Octopus Urn Jan 31 '18 at 18:29
• @MagicOctopusUrn: Too bad. You usually manage to come up with interesting alternatives (and/or improvements) to my solutions. Large programs in golfing languages are certainly more difficult to take the time to work on for sure. – Emigna Jan 31 '18 at 18:58

# Clean, 305 289 bytes

import StdEnv
@[h:t]|all((==)9)h|t>[]=[h: @t]=[h]
#s=length h/2
#m=hd(sort h)+1
=[updateAt(hd[e\\e<-flatten[[s+i,s-i]\\i<-[0..s]]|h!!e<m])m h:t]
$a b c=flatlines(map(cjustify(a+1))[fromString(fromInt(b-c)),['-']:reverse(map(map(toChar o(+)48))((iterate@[repeatn(a-r)0\\r<-[0,2..a]])!!c))])  Try it online! • @KevinCruijssen Fixed. – Οurous Jan 25 '18 at 9:36 # Perl 5, 301 bytes ($x,$t,$u)=<>;$s=$x;$t-=$g=$t>$u?$u:$t;while($s>0){@{$a[++$i]}=((0)x$s,($")x($x-$s));$a[$i][$_%$s]++for 0..($f=$g<$s*9?$g:$s*9)-1;$g-=$f;$s-=2}say$"x(($x-length($g+=$t))/2+.5),$g,$/,$"x($x/2),'-';while(@b=@{pop@a}){for($i=1;$i<@b;$i+=2){print$b[-$i]}print$b[0];for($i=1;$i<@b;$i+=2){print$b[$i]}say''}


Try it online!

# Charcoal, 6863 62 bytes

ＮθＮηＮζＦ⊘⊕θＦ⁹Ｆ⁻θ⊗ι«Ｊ⊘⎇﹪λ²⊕λ±λ±ι≔¬¬ζλ↑Ｉ⁺λＩＫＫ≧⁻λη≧⁻λζ»↑-Ｍ⊘⊖ＬＩη←Ｉη


Try it online! Link is to verbose version of code. Edit: Saved 5 bytes by removing the now-unnecessary index range check. Explanation:

ＮθＮηＮζ


Input the length into q, the number of grains of sand into h and the index into z.

Ｆ⊘⊕θＦ⁹Ｆ⁻θ⊗ι«


Loop over the (q+1)/2 rows (from bottom to top), then 9 grains in each cell in the row, then loop over the digits in the row.

Ｊ⊘⎇﹪λ²⊕λ±λ±ι


≔¬¬ζλ↑Ｉ⁺λＩＫＫ≧⁻λη≧⁻λζ»


If possible, distribute a grain of sand to this digit, decrementing the amount of sand and index left. If we've passed the index, this still converts spaces to zeros, filling the hourglass. The digit is printed upwards because this means that the cursor will be on the neck after the last digit.

↑-


Print the neck.

Ｍ⊘⊖ＬＩη←Ｉη


Centre and print the amount of sand remaining.