Skip to content

Instantly share code, notes, and snippets.

@ppdms
Created November 21, 2023 10:42
Show Gist options
  • Select an option

  • Save ppdms/7409594039c52f5e8fa3efe84042a7a9 to your computer and use it in GitHub Desktop.

Select an option

Save ppdms/7409594039c52f5e8fa3efe84042a7a9 to your computer and use it in GitHub Desktop.

Revisions

  1. ppdms created this gist Nov 21, 2023.
    117 changes: 117 additions & 0 deletions combinations.s
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,117 @@
    .text
    .globl __start

    _start:
    la $a0, pn
    li $v0, 4
    syscall # print prompt for n

    la $v0, 5
    syscall # read n into $v0

    move $t0, $v0 # read n into $t0
    # we can use temp. registers in the entirety of this scope
    # without the danger of side effects changing their contents

    la $a0, pk
    li $v0, 4
    syscall # print promt for k

    la $v0, 5
    syscall # read k into $v0

    move $t1, $v0 # read k into $t1

    blt $t0, $t1, err # assert n >= k
    blt $t1, $zero, err # assert k >=0 (and thus n>=0)

    li $t2, 13 # set $t2 to 13, max(k) + 1
    bge $t1, $t2, bnd # if k is greater or equal to max(k) + 1, error

    la $t2, arr # array address
    li $t3, 4 # word length
    mul $t3, $t1, $t3 # store offset in $t3 (k * 4)
    add $t2, $t2, $t3 # calculate pointer to arr[k] (&arr + k*4)
    lw $t2, ($t2) # load arr[k] to $t2
    blt $t2, $t0, bnd # if n is greater than arr[k], error

    li $t2, 1 # set $t2 to 1
    move $t4, $t0 # store n in $t4 (for printing later)
    move $t5, $t1 # store k in $t5 (for printing later)
    sub $t3, $t0, $t1 # set $t3 to n-k

    blt $zero, $t1, denom # don't have to compute k! if k == 0
    li $t1, 1 # if k == 0, make result 1
    j res # show result in this case

    denom:
    mul $t2, $t1, $t2 # multiply denominator (in $t2) by next factor (in $t1)
    addiu $t1, $t1, -1 # produce next factor ($t1) by -= 1
    blt $zero, $t1, denom # if next factor > 1, continue the loop

    li $t1, 1 # set numerator (in $t1) to 1

    num:
    mul $t1, $t0, $t1 # multiply numerator (in $t1) by next factor (in $t0)
    addiu $t0, $t0, -1 # produce next factor ($t0) by -= 1
    blt $t3, $t0, num # if next factor > n-k, continue the loop

    res:
    div $t1, $t1, $t2 # calculate the fraction C(n, k)

    la $a0, o0
    li $v0, 4
    syscall # print "C("

    move $a0, $t4
    li $v0, 1
    syscall # print n

    la $a0, o1
    li $v0, 4
    syscall # print " ,"

    move $a0, $t5
    li $v0, 1
    syscall # print k

    la $a0, o2
    li $v0, 4
    syscall # print ") = "

    move $a0, $t1
    li $v0, 1
    syscall # print result

    addi $a0, $0, 0xA # ascii for CR
    li $v0, 11
    syscall # print newline

    li $v0, 10
    syscall # exit

    err:
    la $a0, pe
    li $v0, 4
    syscall # print error message

    li $v0, 10
    syscall # exit

    bnd:
    la $a0, warn
    li $v0, 4
    syscall # print error message

    li $v0, 10
    syscall # exit

    .data
    pn: .asciiz "Enter number of objects in the set (n): "
    pk: .asciiz "Enter number to be chosen (k): "
    pe: .asciiz "Please enter n >= k >= 0"
    o0: .asciiz "C("
    o1: .asciiz ", "
    o2: .asciiz ") = "
    arr: .word 2147483647, 2147483647, 46341, 1291, 216, 75, 38, 24, 18, 15, 13, 12, 12
    warn: .asciiz "\nThe values you provided exceeded the limits of this procedure.\nFor all calculations, k must be between 0 and 12. Furthermore,\nfor a given value of k (on the left column) n must not exceed\nthe value given on the right of the same row, for this table:\n\nk n\n0 2147483647\n1 2147483647\n2 46341\n3 1291\n4 216\n5 75\n6 38\n7 24\n8 18\n9 15\n10 13\n11 12\n12 12\n"