| Bytes | Lang | Time | Link |
|---|---|---|---|
| 002 | Uiua | 250718T124254Z | nyxbird |
| 026 | Nim | 250710T021357Z | janAkali |
| 002 | 05AB1E | 250707T070344Z | Kevin Cr |
| nan | Commodore 64 Assembler | 250706T200830Z | Jani Joe |
| 008 | x8664 machine code | 250706T142741Z | m90 |
| 015 | Google Sheets | 250705T183116Z | doubleun |
| 018 | Python 2 | 250706T045802Z | Lucenapo |
| 005 | Charcoal | 250705T193158Z | Neil |
| 002 | Vyxal 3 | 250705T181738Z | Themooni |
| 015 | JavaScript ES6 | 250705T165505Z | Arnauld |
05AB1E, 2 bytes
/î
Inputs in the order decay_per_tick, initial_strength.
Try it online or verify all test cases.
Explanation:
/ # Divide the (implicit) second input by the (implicit) first input
î # Ceil it
# (after which the result is output implicitly)
Commodore 64 Assembler, 25 Bytes (6502/KickAssembler)
Being a purely 8bit processor, including the registers, 6502 can natively handle integers up to 255. As both strength and ticks can be up to 1000, we need to programmatically handle them as 16bit integers, which unfortunately increases the size of our routine quite a bit. An 8bit version of the routine would have taken just 12 bytes.
Input
Before calling the routine:
- Load lo byte of
initial_strengthto Accumulator - Load hi byte of
initial_strengthto Y register - Store
decay_per_tickto memory address $2.
Output
After the routine:
- X register holds the lo byte of the number of ticks
- Memory address $3 holds the hi byte of the number of ticks
Routine
TICKS: ldx #0 // 2 Reset 16bit tick count lo byte.
stx $3 // 2 Reset 16bit tick count hi byte.
zcheck: cmp #0 // 2 Is 16bit aura lo byte 0? Also sets Carry.
bne tick // 2 If not, do tick.
cpy #0 // 2 If yes, is 16bit aura hi byte 0? Also sets Carry.
beq done // 2 If yes, aura is 0 and we're done.
tick: inx // 1 Increment tick count.
bne !+ // 2 Did tick count lo byte roll over?
inc $3 // 2 If it did, increment hi byte.
!: sbc $2 // 2 Subtract decay from aura lo (Carry set by zcheck).
bcs zcheck // 2 If aura lo didn't roll under, check if aura=0
dey // 1 If it did, decrement aura hi.
bpl zcheck // 2 If aura hi didn't roll under, check if aura=0
done: rts // 1 X = tick count lo byte, address $3 = hi byte.
Try It Out (in your favourite IDE or CLI)
To test the routine with the cases listed in the question, and some more, I decided to write a small test suite, because why the heck not. :) Two additional cases are for testing boundaries (1000 max aura, 1000 max ticks, 100 max decay).
BasicUpstart2(tests)
TICKS: ldx #0 // 2 Reset 16bit tick count lo byte.
stx $3 // 2 Reset 16bit tick count hi byte.
zcheck: cmp #0 // 2 Is 16bit aura lo byte 0? Also sets Carry.
bne tick // 2 If not, do tick.
cpy #0 // 2 If yes, is 16bit aura hi byte 0? Also sets Carry.
beq done // 2 If yes, aura is 0 and we're done.
tick: inx // 1 Increment tick count.
bne !+ // 2 Did tick count lo byte roll over?
inc $3 // 2 If it did, increment hi byte.
!: sbc $2 // 2 Subtract decay from aura lo (Carry set by zcheck).
bcs zcheck // 2 If aura lo didn't roll under, check if aura=0
dey // 1 If it did, decrement aura hi.
bpl zcheck // 2 If aura hi didn't roll under, check if aura=0
done: rts // 1 X = tick count lo byte, address $3 = hi byte.
.print "ROUTINE SIZE: " + toIntString(* - TICKS) + " BYTES"
tests: test(10,3,4) // aura, decay, expected ticks
test(5,5,1)
test(0,10,0)
test(1,10,1)
test(1000,1,1000)
test(1000,100,10)
rts
.macro test(aura, decay, expected) {
GIVEN: lda #decay // Load decay to A...
sta $2 // ...and store it to ZP address $2.
lda #<aura // Load 16bit aura lo byte to A.
ldy #>aura // Load 16bit aura hi byte to Y.
WHEN: jsr TICKS // CALL OUR ROUTINE.
THEN: lda $3 // Load aura hi byte to A
cmp #>expected // Compare with hi byte of expected ticks
bne fail // If no match, branch to fail
cpx #<expected // Compare lo byte of ticks to expected
bne fail // If no match, branch to fail
succ: print(s_act) // Otherwise, print success message.
jsr $bdcd // Call ROM routine to print out 16bit integer.
lda #$0d // Call ROM routine to print out $0d (control
jsr $ffd2 // code for pressing RETURN key).
jmp done // Test done.
fail: print(f_act) // Print 1st (actual) part of fail message.
jsr $bdcd // Call ROM routine to print out 16bit integer.
print(f_exp) // Print 2nd (expected) part of fail message.
lda #>expected // Load hi byte of expected ticks to A...
ldx #<expected // ...and lo byte to X.
jsr $bdcd // Call ROM routine to print out 16bit integer.
lda #$0d // Call ROM routine to print out $0d (control
jsr $ffd2 // code for pressing RETURN key).
done: // Test completed.
}
.macro print(message) {
pha // Push A to stack.
tya // Move Y to A...
pha // ...and push it to stack as well.
ldy #0 // Y=0
!: lda message,y // Load char,y from message
beq done // If zero (null), we're done.
jsr $ffd2 // Print char.
iny // Increment char index.
bne !- // If not rolled over, keep printing chars.
done: pla // Pull value of Y from stack to A...
tay // ...and move it to Y.
pla // Pull value of A from stack.
}
f_act: .te "TEST FAILED! TICKS: " ; .by 0
f_exp: .te ", EXPECTED: " ; .by 0
s_act: .te "TEST PASSED! TICKS: " ; .by 0
x86-64 machine code, 8 bytes
8D 44 37 FF 99 F7 F6 C3
Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes initial_strength and decay_per_tick as 32-bit integers in EDI and ESI, respectively, and returns a 32-bit integer in EAX.
In assembly:
f: lea eax, [rdi + rsi - 1] # Set EAX to the sum of the two values minus 1.
cdq # Sign-extend EAX, preparing for the next instruction.
div esi # Divide by the decay value. The quotient goes into EAX.
ret # Return.
Google Sheets, 15 bytes
=ceiling(A1/B1)
Put initial_strength in cell A1, decay_per_tick in B1 and the formula in C1.
Charcoal, 5 bytes
I⌈∕NN
Try it online! Link is to verbose version of code. Explanation: Suffers from potential floating-point inaccuracy.
N First input as a number
∕ Floating-point division by
N Second input as a number
⌈ Ceiling
I Cast to string
Implicitly print
There are a couple of approaches for precise arithmetic for 6 bytes:
I⊕÷⊖NN
Try it online! Link is to verbose version of code. Explanation: Decrements the numerator first, then increments the result.
I±÷±NN
Try it online! Link it to verbose version of code. Explanation: Negates the numerator, which turns the flooring effect of integer divide into a ceiling effect, then negates the result.
With all of the above answers, two bytes can be saved by taking input in JSON format e.g. [10, 3] which allows the Ns to be removed.
Vyxal 3, 2 bytes
÷⌈
÷⌈
÷ # div
⌈ # ceil
💎
Created with the help of Luminespire.
<script type="vyxal3">
÷⌈
</script>
<script>
args=[["3","10"],["5","5"],["10","0"],["10","1"]]
</script>
<script src="https://themoonisacheese.github.io/snippeterpreter/snippet.js" type="module"/>
JavaScript (ES6), 15 bytes
Expects (initial_strength)(decay_per_tick).
s=>d=>~-s/d+1|0
