Page 2 of 2
Posted: Mon Dec 07, 2009 1:18 pm
by livinskull
I did this bit for bit, as for the first thought I had was to print the result in binary...
So my code is kinda big with 115 instructions
Code: Select all
88*8*8*8*8*8*8*8*8*0<1^:1+93+?0<1^-0>12>3g02>1<1^:1+93+?1<1^-1>13>3g03>2<3<:7?4<1^+4>21^:8?2/99+1+c0<1<:6?4<1+4>4<p
Initially coded that shit in asm to see how it would look like.. unfortunately my assembler still has its problems with jumps etc... so I translated the asm to hvm by hand
Code: Select all
preserve 2
var divisor 1073741824
var result
start:
push [0]
push divisor
jl skip_sub
sub [0],divisor
mov [2],1
jmp second_number
skip_sub:
mov [2],0
second_number:
push [1]
push divisor
jl skip_sub2:
sub [1],divisor
mov [3],1
jmp numbers_done
skip_sub2:
mov [3],0
numbers_done:
push [2]
push [3]
je dont_add
add result,divisor
dont_add:
push 2
push divisor
je last_one
div divisor,2
jmp start
last_one:
push [0]
push [1]
je nothing
add result,1
nothing:
pi result
Urgently need to resume working on my hvm assembler :3
Posted: Fri Mar 26, 2010 3:46 pm
by jonik555
LoL. Maybe I'm just too young for codes like these posted there...
Code: Select all
32>0<21^1^/*-2<>2<1+2>0<2/0>0<2?3c
76*2>2<1+2<>
1<21^1^/*-2<<>2<<1+2<>1<2/1>1<6?58*8+c
30>2<1+1>994**2>52<1->
0<<1<<:4?12<>0<1+<1:1-55*?0<1+0>1<1+1>2<1+2>087*-g
994**0>11>02>
0<<1<*2<+2>1<2*1>0<1+0>1<8888888******:7?077*-g
2<p!
Posted: Fri Jul 22, 2011 6:35 am
by DaymItzJack
Code: Select all
03>1 # push the total into memory cell 3, keep the 'counter' on
# the stack starting at 1
0<1< # take both numbers off memory
0^2/0^2*2v1v- # divide the number by 2 and find the remainder and get
# the bit
2v # move number 2 up to the top
0^2/0^2*2v1v- # divide the number by 2 and find the remainder and get
# the bit
2v # move number 1 up to the top
-7? # if they are the same (0-0=0, 1-1=0), skip
#"adding counter to total"
3<3^+3> # take memory cell out to the stack, add counter to it
2v2* # increase counter, it goes in the order 1, 2, 4, 8...
1v2v # put num1 and num2 back on top
1^1^-8?088*1--g # check if both num1 and num2 are 0, terminate if they are
3<p
Posted: Fri Aug 19, 2011 5:51 am
by compudemon
102>0<0<2/0^0>2*-1<1<2/0^1>2*--3?11g01^*2<+2>2*0<1<+6?078*-g2<p
fairly straight forward solution
Posted: Tue Jan 17, 2012 9:48 am
by rmplpmpl
62*62**1+g2<2<2/2>2<2*-3<>2<2?1g$3<1+3>01-66**3-g3<<4<<-6?15<>4g05<>3<1+3>4<1+4>5<1+5>3<85*1+-2?1g$01-69**6-g5<<4<*6<+6>5<583**-2?1g$4<2*4>5<1+5>01-77**3+g0<2>91+3>55+c1<2>77*1+3>55+c91+3>77*1+4>55+9*5>77*c67+7*5>5<1-<6>24>554**9+c6<p
...good thing hacker.org is up again, I'll need to analyze the much shorter solutions for this...
Posted: Fri Jun 29, 2012 7:00 am
by TheBigBoss
Okay, here's the shortest one:
0<1<8cp!1^1^:55*1+?1^2/1^2/8c2*2v2v+0^2/2*-+$dd0$
It works with all integers of any size, does not corrupt the memory and cleans both its stack and call stack!
Posted: Fri Aug 23, 2013 11:23 am
by wischi
I wrote a little hvm-compiler (quick and dirty, at the moment only basic features) which support some inline functions (like mod) and calculates the jumps
My MetaHVM_0.0.1 Code
Code: Select all
##MetaHVM_0.0.1
#x = M0 (initialized)
#y = M1 (initialized)
#s = M2
#r = M3
12> #s=1
03> #r=0
[:begin_while]
0<1<+[!end]? #Condition (break if x = 0 And y=0) (load x,load y,add,jump if zero)
0<2(mod) #push x mod 2 to Stack
1<2(mod) #push y mod 2 to Stack
-[!skip]? #if equal then skip
3<2<+3> #r += s (load r, load s, add, write r)
[:skip]
0<2/0> #x /= 2;
1<2/1> #y /= 2;
2<2*2> #s *= 2;
[!begin_while]g
[:end]
3<p
Result
Code: Select all
12>03>0<1<+397*+ ?0<21^1^/*-1<21^1^/*--7 ?3<2<+3>0<2/0>1<2/1>2<2*2>099*- g3<p
Of course not the shortest way, and the gaps for the jumps are a bit annoying (each "Address" is 9 chars long and supports relative jumps from -820 to +828 - maybe i will make it dynamic in the future)
And maybe there will be structures and blocks (like if,for,while,...) in later MetaHVM versions
Posted: Wed Feb 26, 2014 1:29 pm
by Tabun
I'm also writing a HVM compiler that turns a C-like script language (which I call PreHVM) into a working HVM program. Kinda like witschi, only I went overboard: I made it track 'variables' on the stack, evaluate complex expressions with almost all operators C uses, with if/elseif/else and while structures and so on. It also does do fairly efficient overlapping jump resolution, so it doesn't rely on whitespace room.
Solution for this one was generated from:
Code: Select all
var val_a = mget(0);
var val_b = mget(1);
// find the highest factor of 2
var x = 1;
while (x < val_a || x < val_b) {
x = x * 2;
}
// for each factor of two, add up the ones that are only present for one of the two
var val_c;
while (x > 0) {
if (val_a >= x ^ val_b >= x) {
val_c = val_c + x;
}
if (val_a >= x) {
val_a = val_a - x;
}
if (val_b >= x) {
val_b = val_b - x;
}
x = x / 2;
}
print val_c;
Very fun project, though it doesn't exactly generate optimal HVM yet. This generated a 240 command program. I know that's HUGE still, and it only uses relative jumps.
It should be a bit smaller once I optimize comparison/condition checks for the ifs/loops and some tricks. For now, though, I'm just having fun making it work -- and I do like keeping memory 'clean' by default, if I can.
Posted: Wed Feb 28, 2018 8:57 am
by _romanchick_
This is my code. Not too short, but it uses no :. So it can be usefull later...
0 13> 0<0<2/2*-1<1<2/2*-+5>5<5<2/2*- 3<*+ 0<2/0>1<2/1> 3<2*3> 0<1<+3?6c p
Re: Exclusive Or
Posted: Fri Oct 06, 2023 12:25 am
by adark
I went about this totally by hand, and boy was that a pain in the butt. Definitely need to build myself a debugger for HVM + SuperHack! Wrote this to be agnostic about the size of the operands!
A slight optimization would be to swap the memory cells if M[0] < M[1], saving a handful of cycles on the later iterations once the smaller value reaches 0 during the first loop. An even better optimization that I *should* have done is storing the result value on the stack instead of using M[2], saving 8 cycles *every* iteration of the first loop! This also leaves a "garbage" value on the call stack, so I'd have to rewrite Loop 1 some to embed this in another HVM program.
Code: Select all
07c06-g 0<0:3?7g 1<0:3?6g 68*g 1+0<0^2/0^0>2*- 1<0^2/0^1>2*- 2<2*2v2v:2?1+2> $ 02<2v0^0:1-4?ddp!1-1^0^2/2*-3v2*+2v2/05-7*7-g
Commented:
Code: Select all
0 # initialize bit counter to 0
# Loop 1:
7c06-g # call-based loop header
0<0:3?7g # if M_0 is 0, go to M_1 check, else enter loop body (jumps to M_1 check's `6g`)
1<0:3?6g 68*g # if M_1 is 0, go to the bit-reversal routine, else enter loop body
# LOOP BODY:
1+ # increment bit counter
0<0^2/0^0>2*- # Compute the LSB of M_0 + store M_0 /= 2
1<0^2/0^1>2*- # Compute the LSB of M_1 + store M_1 /= 2
# explained:
# n< # load M_n
# 0^ # duplicate it
# 2/ # integer divide duplicate by 2
# 0^n> # duplicate and store result back into M_n
# 2*- # double result and subtract this from original
# By integer division, this computes the LSB of M_n
# stack is now [n+1, (original M_0 >> n)&1, (original M_1 >> n)&1]
2<2* # load result from M_2 (initially 0 by default) and left-shift it 1 bit
2v2v:2? # pull out the 2 bits of M_0 and M_1 and compare them
1+ # if they're *not* equal, add 1 to result
2> # store result back into M_2
$ # GOTO Loop 1
# bit-reversal routine
02< # initialize "correct" result, and load reversed result from M_2
# Loop 2:
# stack is now [n, result, reversed], where `n` bits still need to be copied from `reversed` to `result`
2v0^0: # move n to top of stack, duplicate and compare to 0
1-4? # if n > 0, skip over the exit
ddp! # exit, drop `n` and `reversed`, print `result`!
1- # decrement n
1^0^ # duplicate `reversed` twice
2/2*- # extract its current LSB
3v2*+ # move `result` to top of the stack, << 1 and add `reversed`'s LSB
2v2/ # move `reversed` to top of the stack, >> 1
05-7*7-g # GOTO Loop 2