• 100 Random Single Variable Linear Equations

    From Mike Sanders@21:1/5 to All on Fri Dec 6 03:46:32 2024
    Beware wordwrap...

    # algebra.awk: 2024 - Michael Sanders
    #
    # usage: awk -f algebra.awk > solve.txt
    #
    # outputs 100 random single variable linear equations in the form: ax+b=c
    #
    # where...
    #
    # a, b, & c are constants (numbers)
    # x is the variable
    #
    # example output...
    #
    # 001. 18x * 20 = 27
    # 002. 1x * 16 = 31
    # 003. 10x / 8 = 16
    #
    # solving for x...
    #
    # 1. solving for x means finding the value of x that makes the equation true.
    #
    # 2. how to do it:
    # - look at the equation & see if x is combined with numbers or other terms. # - use inverse operations to "cancel out" numbers or terms that are with x. #
    # for example:
    # - if x is multiplied by a number, divide both sides of the equation by that number.
    # - if x is divided by a number, multiply both sides of the equation by that number.
    # - if x is added to a number, subtract that number from both sides.
    # - if x has a number subtracted from it, add that number to both sides.
    #
    # 3. example, solve for x in the equation: 2x + 5 = 11
    #
    # - step 1: subtract 5 from both sides:
    # to remove the +5 from the left side, subtract 5 from both sides:
    # (2x + 5) - 5 = 11 - 5
    #
    # simplify:
    # 2x = 6
    #
    # - step 2: divide both sides by 2:
    # to remove the 2 multiplying x, divide both sides by 2:
    # (2x) / 2 = 6 / 2
    #
    # simplify:
    # x = 3
    #
    # 4. final answer: x = 3
    #
    # 5. why it works:
    # you perform the same operation on both sides of the equation,
    # keeping it balanced, until x is by itself on one side.
    #
    # further reading: https://en.wikipedia.org/wiki/Algebra

    BEGIN {
    srand() # seed random number generator

    for (q = 1; q <= 100; q++) {
    # generate random coefficients & constant
    a = int(rand() * 20) + 1 # random value for 'a' (1 to 20)
    b = int(rand() * 20) + 1 # random value for 'b' (1 to 20)
    c = int(rand() * 50) + 1 # random value for 'c' (1 to 50)

    opc = (rand() < 0.5 ? "*" : "/") # random operator
    lhs = sprintf("%dx %s %d", a, opc, b) # left-hand side
    rhs = c # right-hand side

    # format equation number with zero-padding
    equation = sprintf("%03d", q)

    # blank lines after equations
    bla = sprintf("\n\n\n\n\n\n\n\n\n")

    # print formated equation
    printf("%s. %s = %d%s", equation, lhs, rhs, bla)

    }
    }

    # eof

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Mike Sanders on Fri Dec 6 04:51:54 2024
    Mike Sanders <porkchop@invalid.foo> wrote:

    # algebra.awk: 2024 - Michael Sanders
    #
    # usage: awk -f algebra.awk > solve.txt

    [...]

    # subtle tweak: every equation unique (no duplicates)...

    BEGIN {
    srand() # seed the random number generator

    # keep generating until we have exactly 100 unique equations
    while (u < 100) {
    a = int(rand() * 20) + 1 # random value for 'a' (1 to 20)
    b = int(rand() * 20) + 1 # random value for 'b' (1 to 20)
    c = int(rand() * 50) + 1 # random value for 'c' (1 to 50)

    opc = (rand() < 0.5 ? "*" : "/") # random operator
    lhs = sprintf("%dx %s %d", a, opc, b) # left-hand side
    rhs = c # right-hand side
    equ = lhs " = " rhs # full equation

    # store equation in array if it doesn't already exist
    if (!(equ in equations)) {
    equations[equ] = 1 # mark element as 'reserved'...
    u++ # increment u for each unique equation
    }
    }

    # print equations
    for (e in equations) printf("%03d. %s\n\n\n\n\n\n\n\n\n", ++q, e)
    }

    # eof

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Janis Papanagnou on Fri Dec 6 13:59:28 2024
    On 06.12.2024 13:43, Janis Papanagnou wrote:
    Hi Mike,

    is my guess correct that you want to create linear equation samples
    to be printed (on paper) and solved? Or is it meant as a programming
    course sample? - My suggestions depend on being one or the other...
    [...]

    The program could be extended by two principle additions/changes.

    One is to allow negative integral numbers for a, b, c; in that case
    you don't even need the "random operator" logic as a side effect.
    Since you are using only natural numbers in your formulas you may
    want to stay within the domain of integral numbers also in the
    results; that would require to check that condition before storing
    an accepted formula, or to synthesize such formulas in the first
    place.

    Just some more ideas.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Mike Sanders on Fri Dec 6 13:43:25 2024
    Hi Mike,

    is my guess correct that you want to create linear equation samples
    to be printed (on paper) and solved? Or is it meant as a programming
    course sample? - My suggestions depend on being one or the other...

    I've learned linear equations to contain an additive term, as in
    a x + b = c (i.e. a*x + b == c written as Awk expression),
    so I'd have expected the operator to be '+' or '-' (not '*' or '/'). (Otherwise, with a*x * b , you could just calculate a*b first and
    a/b respectively, in case of a division a*x / b, before then doing
    the single final lhs/rhs operation. The "both sides" procedures
    you describe in your introductory comment would be unnecessarily
    complicate if you really meant * and / .)

    I wonder about the many temporary variables and technical comments;
    most don't contribute to legibility or clearness and are unnecessary.
    There could be used better naming for the remaining fewer variables.
    It could gain from more structuring, like using a 'random' function
    for integers to make the random expressions simpler.
    Control structure could be simplified, made clearer; do { } while . Re-iterating over the stored equations is unnecessary, you can just
    print them.

    (I've added code reflecting these suggestions at the end of my post
    in case you'd like to pick an idea or two. I've also changed a few
    more details, just in case you wonder about any differences to the
    original code.)

    Janis


    On 06.12.2024 05:51, Mike Sanders wrote:
    Mike Sanders <porkchop@invalid.foo> wrote:

    # algebra.awk: 2024 - Michael Sanders
    #
    # usage: awk -f algebra.awk > solve.txt

    [...]

    # subtle tweak: every equation unique (no duplicates)...

    BEGIN {
    srand() # seed the random number generator

    # keep generating until we have exactly 100 unique equations
    while (u < 100) {
    a = int(rand() * 20) + 1 # random value for 'a' (1 to 20)
    b = int(rand() * 20) + 1 # random value for 'b' (1 to 20)
    c = int(rand() * 50) + 1 # random value for 'c' (1 to 50)

    opc = (rand() < 0.5 ? "*" : "/") # random operator
    lhs = sprintf("%dx %s %d", a, opc, b) # left-hand side
    rhs = c # right-hand side
    equ = lhs " = " rhs # full equation

    # store equation in array if it doesn't already exist
    if (!(equ in equations)) {
    equations[equ] = 1 # mark element as 'reserved'...
    u++ # increment u for each unique equation
    }
    }

    # print equations
    for (e in equations) printf("%03d. %s\n\n\n\n\n\n\n\n\n", ++q, e)
    }

    # eof



    function rnd (n) # n -> 1..n
    {
    return int(rand() * n) + 1
    }

    BEGIN {
    srand()

    while (++serial_number <= 100) {
    do {
    opc = rand() < 0.5 ? "+" : "-" # choose random operator
    equ = sprintf("%d x %c %d = %d", rnd(20), opc, rnd(20), rnd(50))
    } while (equ in equations_store) # avoid duplicates

    equations_store [equ] # memorize generated equation

    printf("%3d.\t%s\n", serial_number, equ)
    }
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Janis Papanagnou on Fri Dec 6 13:38:01 2024
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    Hi Mike,

    Hey Janis =)

    is my guess correct that you want to create linear equation samples
    to be printed (on paper) and solved? Or is it meant as a programming
    course sample? - My suggestions depend on being one or the other...

    Just a quick project, nothing serious. Really just thinking aloud
    and hoping some of you might offer up your thoughts. Really great
    suggestions, I think I'll add some of your ideas to it in the next
    few days.

    I've learned linear equations to contain an additive term, as in
    a x + b = c (i.e. a*x + b == c written as Awk expression),
    so I'd have expected the operator to be '+' or '-' (not '*' or '/'). (Otherwise, with a*x * b , you could just calculate a*b first and
    a/b respectively, in case of a division a*x / b, before then doing
    the single final lhs/rhs operation. The "both sides" procedures
    you describe in your introductory comment would be unnecessarily
    complicate if you really meant * and / .)

    Ahh but I do like the 'spice' of '*' & '/' (see latest iteration below).

    But I do wonder about: 5x vs. 5 * x or even (5 * x)... I've read so many opinions on this matter. If there an offical standard? I dont know.

    One older book I have (from 1917!) has 1-2 paragraphs saying 5x without
    an intervening * is very bad form & yet, everybody seems to use it, at
    least here the USA.

    I wonder about the many temporary variables and technical comments;
    most don't contribute to legibility or clearness and are unnecessary.
    There could be used better naming for the remaining fewer variables.
    It could gain from more structuring, like using a 'random' function
    for integers to make the random expressions simpler.
    Control structure could be simplified, made clearer; do { } while . Re-iterating over the stored equations is unnecessary, you can just
    print them.

    I know, more clean ups are needed. But the embedded documentation
    ought to be included IMO, though, it is terribly messy...

    (I've added code reflecting these suggestions at the end of my post
    in case you'd like to pick an idea or two. I've also changed a few
    more details, just in case you wonder about any differences to the
    original code.)

    Yes, certainly, let me study & consider your code & see if I can weave
    it into the project. Sounds interesting.


    function rnd (n) # n -> 1..n
    {
    return int(rand() * n) + 1
    }

    BEGIN {
    srand()

    while (++serial_number <= 100) {
    do {
    opc = rand() < 0.5 ? "+" : "-" # choose random operator
    equ = sprintf("%d x %c %d = %d", rnd(20), opc, rnd(20), rnd(50))
    } while (equ in equations_store) # avoid duplicates

    equations_store [equ] # memorize generated equation

    printf("%3d.\t%s\n", serial_number, equ)
    }
    }


    Yeah I like your thinking, nice & clear. Solid stuff. I'll put some of
    this to work during Christmas.

    Here's my latest (before I saw your reply). Checkout 'z', sort of like
    a gear in a machine yeah? 'n' too. But my imagination is running wild...

    BEGIN {
    srand() # seed random number generator

    # keep generating until we have exactly 100 unique equations
    while (u < 100) {
    a = int(rand() * 20) + 1 # random value 1 to 20
    b = int(rand() * 20) + 1 # random value 1 to 20
    c = int(rand() * 50) + 1 # random value 1 to 50
    z = substr("*-/+", (++q % 4) + 1, 1) # cycle operators
    e = sprintf("%dx %s %d = %d", a, z, b, c) # formatted equation

    # store equation in array if it doesn't already exist
    if (!(e in equ)) {
    equ[e] = 1 # mark element as reserved
    u++ # increment u for each unique equation
    }
    }

    # print equations
    for (j in equ) printf("%03d. %s\n\n\n\n\n\n\n", ++n, j)
    }

    # eof

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Mike Sanders on Fri Dec 6 21:01:20 2024
    On 06.12.2024 14:38, Mike Sanders wrote:
    [...]

    But I do wonder about: 5x vs. 5 * x or even (5 * x)... I've read so many opinions on this matter. If there an offical standard? I dont know.

    In printed (math) textbooks an explicit multiplication operator is
    normally omitted, so you see 5 x (or 5x , but I prefer a visible
    significant separation, if only to not mis-read "5x" as "5 times").
    There's also expressions like 5 x 6 where the 'x' is another form
    of the multiplication operator; but in math (algebra) this is an
    inappropriate syntax since you typically have variables named 'x'.
    The explicit operator '*' you see is just the common multiplication
    operator that is used in computer programs, and it is often used in
    technical communication to be able to formulate a clear syntax that
    is unambiguous and easy to understand (and can be clearly parsed in expressions).

    For documentation I'd use the most obvious form that leads to least
    confusion. It also depends on context, who's reading the text. It's
    certainly easier (IMO) to grasp formulas like
    a x^2 + b x + c = 0
    than
    a * x^2 + b * x + c = 0
    especially if there are a lot of multiplication factors. But I may
    be biased by education. For communication in computer contexts I'd
    use the latter.

    One older book I have (from 1917!) has 1-2 paragraphs saying 5x without
    an intervening * is very bad form & yet, everybody seems to use it, at
    least here the USA.

    It's amazing that the old book you're referring to mentions '*' as multiplication. Were I live, either the multiplication operator is
    omitted (in books), or explicitly written as '·' (middle-dot), and
    rarely (often in classic mercantile contexts) they use 'x', which
    is, typographically actually another character (the '×', a smaller
    sized middle-x). The '*', as said, in computer contexts, but I've
    never seen it in our math books (unless computer related).

    If the '*' is [in the USA] suggested in books that would probably
    explain the choice of that character for computer programs' syntax.

    Janis

    [...]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Keith Thompson on Fri Dec 6 22:05:30 2024
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    porkchop@invalid.foo (Mike Sanders) writes:
    [...]
    One older book I have (from 1917!) has 1-2 paragraphs saying 5x without
    an intervening * is very bad form & yet, everybody seems to use it, at
    least here the USA.
    [...]

    Can you identify the book? It's likely to be in the public domain, and perhaps available online.

    Hi Keith. I'll check that, stay tuned...

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Mike Sanders on Fri Dec 6 22:04:16 2024
    Mike Sanders <porkchop@invalid.foo> wrote:

    Yes, certainly, let me study & consider your code & see if I can weave
    it into the project. Sounds interesting.

    ok, a start, but still need to rework loop, hopefully this weekend.

    also added global SEED allowing for re-use...

    awk -f algebra.awk -v SEED=$RANDOM

    BEGIN {

    SEED = SEED ? SEED : 1

    srand(SEED) # seed random number generator

    # keep generating until we have exactly 100 unique equations
    while (u < 100) {
    a = rnd(1, 20) # random value 1 to 20
    b = rnd(1, 20) # random value 1 to 20
    c = rnd(1, 50) # random value 1 to 50
    z = (rnd(1, 2) == 1) ? "+" : "-" # safe/janis: random operator
    # z = substr("*-/+", (++q % 4) + 1, 1) # wild/mike: cycle operators
    e = sprintf("%dx %s %d = %d", a, z, b, c) # formatted equation

    # store equation in array if it doesn't already exist
    if (!(e in equ)) {
    equ[e] = 1 # mark element as reserved
    u++ # increment u for each unique equation
    }
    }

    # print equations
    printf("SEED: %d\n\n", SEED)
    for (j in equ) printf("%03d. %s\n\n\n\n\n\n\n", ++n, j)
    }

    function rnd(min, max) { return int(rand() * (max - min + 1)) + min }

    # eof

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Weisgerber@21:1/5 to Janis Papanagnou on Fri Dec 6 23:05:33 2024
    On 2024-12-06, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    One older book I have (from 1917!) has 1-2 paragraphs saying 5x without
    an intervening * is very bad form & yet, everybody seems to use it, at
    least here the USA.

    It's amazing that the old book you're referring to mentions '*' as multiplication.

    I suspect Mike used '*' as as short-hand for "a multiplication
    sign" and not specifically the asterisk.

    If the '*' is [in the USA] suggested in books that would probably
    explain the choice of that character for computer programs' syntax.

    I don't think that's the case. But now I wonder, where did the use
    of the asterisk as multiplication sign come from? ... Wikipedia
    suggests it originated in Fortran, due to the restrictions of early
    character sets.

    While the multiplication sign '×' is sometimes used as such (and
    also for the vector cross product), the division sign '÷' is limited
    to calculator keypads and never encountered anywhere else that I
    can think of.

    --
    Christian "naddy" Weisgerber naddy@mips.inka.de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Christian Weisgerber on Sat Dec 7 01:36:01 2024
    Christian Weisgerber <naddy@mips.inka.de> wrote:

    I suspect Mike used '*' as as short-hand for "a multiplication
    sign" and not specifically the asterisk.

    Yes that's exactly the case (sorry for any confusion folks).

    The code simply generates problems for the student/enthusiast
    to solve. The books I've read use the symbols we all know.
    But some older books complained that: 5y is ambiguous &
    would be better expressed as: 5 * y, where * is the actual
    multiplication symbol in the book & y is the variable.

    In the code posted, I'm using 7bit ASCII for all operators:

    * multiplication 2 * 2 = 4

    / division 4 / 2 = 2

    + addition 2 + 2 = 4

    - subtraction 2 - 2 = 0

    ^ power 2 ^ 2 = 4

    _nth subscript a_1 (1st element in array a[1])

    % modulus

    < less than

    greator than

    & and

    | or

    (), [], {} order does not matter, evaluate inner
    to outer before outside expressions
    {2 / [(x + y + z) - 2]}

    r! factorial 4! = 4 * 3 * 2 * 1 = 24

    = equals

    != not equal

    ~ approximately equal

    f(a, b) = a + 10 function definition

    how to handle matrices?

    [x y
    0 1]

    [x y]
    [0 1]

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Mike Sanders on Sat Dec 7 02:06:34 2024
    Mike Sanders <porkchop@invalid.foo> wrote:

    Hi Keith. I'll check that, stay tuned...

    1 (or more) of the books below mention the form '5y' as being
    ambiguous vs. '5 * y'. The book(s) used the actual multiplication
    symbol when discussing the matter. All can be had in PDF format.

    I cant remember exactly where & which, but its there... have fun.

    https://archive.org/details/algebraforbeginn00bradrich/mode/2up

    https://archive.org/details/algebraforbeginn00hall/mode/2up

    https://archive.org/details/firstcourseinalg0000hawk/page/n7/mode/2up

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Mike Sanders on Sat Dec 7 01:49:30 2024
    Mike Sanders <porkchop@invalid.foo> wrote:

    [...]
    SEED = SEED ? SEED : 1
    [...]

    no, no, what am i thinking, better expressed as:

    if (!SEED) SEED = 1

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Janis Papanagnou on Sat Dec 7 02:39:08 2024
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    The program could be extended by two principle additions/changes.

    One is to allow negative integral numbers for a, b, c; in that case
    you don't even need the "random operator" logic as a side effect.
    Since you are using only natural numbers in your formulas you may
    want to stay within the domain of integral numbers also in the
    results; that would require to check that condition before storing
    an accepted formula, or to synthesize such formulas in the first
    place.

    I too want to do this, but will need help when the time comes...

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Mike Sanders on Sat Dec 7 03:21:34 2024
    On 07.12.2024 02:49, Mike Sanders wrote:
    Mike Sanders <porkchop@invalid.foo> wrote:

    [...]
    SEED = SEED ? SEED : 1
    [...]

    no, no, what am i thinking, better expressed as:

    if (!SEED) SEED = 1


    A deliberately chosen seed of 0 gets overwritten?

    How about (since you're expecting a number)

    if (SEED=="") SEED = 1

    or (for good measure) the more general pattern for
    an "uninitialized" variable 'var'

    if (var=="" && var==0) ... # uninitialized
    else ... # initialized (including "" and 0)

    But is a seed of 1 "better" than a seed of 0 ?
    Both create deterministic random number sequences.

    Only srand() (i.e. without argument) creates a
    time-depending quasi non-deterministic sequence.

    My choice would probably be

    if (var=="" && var==0) srand() # random start
    else srand(var) # deterministic

    to have both options.

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Janis Papanagnou on Sat Dec 7 20:42:11 2024
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    The program could be extended by two principle additions/changes.

    One is to allow negative integral numbers for a, b, c; in that case
    you don't even need the "random operator" logic as a side effect.
    Since you are using only natural numbers in your formulas you may
    want to stay within the domain of integral numbers also in the
    results; that would require to check that condition before storing
    an accepted formula, or to synthesize such formulas in the first
    place.

    Just some more ideas.

    'n' (at least for leading coefficient). but... this only tackles 'a'.

    'b' & 'c' remain untouched. i must think about this more...

    do {
    a = rnd(1, 20) # random value 1 to 20
    b = rnd(1, 20) # random value 1 to 20
    c = rnd(1, 99) # random value 1 to 50
    z = (rnd(1, 2) == 1) ? "+" : "-" # random operator
    n = (rnd(1, 2) == 1) ? "-" : "" # random negative coefficient
    e = sprintf("%s%dx %s %d = %d", n, a, z, b, c) # formatted equation

    # Store equation in array if it doesn't already exist
    if (!(e in equ)) {
    equ[e] = 1 # mark element as reserved
    u++ # increment u for each unique equation
    }

    } while (u < 100)

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Mike Sanders on Sun Dec 8 06:06:59 2024
    Mike Sanders <porkchop@invalid.foo> wrote:

    # outputs 100 random single variable linear equations in the form: ax+b=c

    now randomly creates up to 2 instances of 'x' per equation & 3 random forms...

    ax op1 b = c
    ax op1 bx = c
    ax op1 b op2 x = c

    (really more than 3 if there's a leading negtive)

    and unless there's something out of whack, i'm using this version, because algebra can melt my brain as it increases in complexity...

    BEGIN {
    # seed random number generator
    if (SEED+0 != SEED) SEED = 1; srand(SEED)

    # keep generating until we have exactly 100 unique equations
    do {
    a = rnd(1, 20) # random value for coefficient x
    b = rnd(1, 99) # random value for b constant
    c = rnd(1, 99) # random value for c constant
    n = (rnd(1, 2) == 1) ? "-" : "" # random negative for coefficient x
    f = rnd(1, 3) # random equation form
    op1 = rop() # random operator

    if (f == 1) {
    # simple equation: ax op1 b = c
    e = sprintf("%s%dx %s %d = %d", n, a, op1, b, c)
    } else if (f == 2) {
    # medium complexity: ax op1 bx = c
    b2 = rnd(1, 20) # new/different coefficient for 2nd x
    op2 = rop() # 2nd random operator
    e = sprintf("%s%dx %s %dx = %d", n, a, op1, b2, op2, c)
    } else if (f == 3) {
    # more complex: ax op1 b op2 x = c
    op2 = rop() # 2nd random operator
    e = sprintf("%s%dx %s %d %s x = %d", n, a, op1, b, op2, c)
    }

    # store equation in array if it doesn't already exist
    if (!(e in equ)) {
    equ[e] = 1 # mark element as reserved
    u++ # increment u for each unique equation
    }

    } while (u < 100)

    # print seed & equations
    printf("SEED: %d\n\n", SEED)
    for (j in equ) printf("%03d. %s\n", ++i, j)
    }

    function rop() { return substr("+-*/", rnd(1, 4), 1) }

    function rnd(min, max) { return int(rand() * (max - min + 1)) + min }

    # eof

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Janis Papanagnou on Sun Dec 8 06:40:33 2024
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    A deliberately chosen seed of 0 gets overwritten?

    How about (since you're expecting a number)

    if (SEED=="") SEED = 1

    or (for good measure) the more general pattern for
    an "uninitialized" variable 'var'

    if (var=="" && var==0) ... # uninitialized
    else ... # initialized (including "" and 0)

    But is a seed of 1 "better" than a seed of 0 ?
    Both create deterministic random number sequences.

    Only srand() (i.e. without argument) creates a
    time-depending quasi non-deterministic sequence.

    My choice would probably be

    if (var=="" && var==0) srand() # random start
    else srand(var) # deterministic

    to have both options.

    See downthread, tell me what you think please kind sir...

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Mike Sanders on Sun Dec 8 07:16:06 2024
    Mike Sanders <porkchop@invalid.foo> wrote:

    and unless there's something out of whack, i'm using this version...

    } else if (f == 2) {
    # medium complexity: ax op1 bx = c
    b2 = rnd(1, 20) # new/different coefficient for 2nd x
    op2 = rop() # 2nd random operator
    e = sprintf("%s%dx %s %dx = %d", n, a, op1, b2, op2, c)
    }...

    in form 2 (f==2) e is incorrect (op2...), but fixed now:

    BEGIN {
    # seed random number generator
    if (SEED+0 != SEED) SEED = 1; srand(SEED)

    # keep generating until we have exactly 100 unique equations
    do {
    a = rnd(1, 20) # random value for coefficient x
    b = rnd(1, 99) # random value for b constant
    c = rnd(1, 99) # random value for c constant
    n = (rnd(1, 2) == 1) ? "-" : "" # random negative for coefficient x
    f = rnd(1, 3) # random equation form
    op1 = rop() # random operator

    if (f == 1) {
    # simple equation: ax op1 b = c
    e = sprintf("%s%dx %s %d = %d", n, a, op1, b, c)
    } else if (f == 2) {
    # medium complexity: ax op1 b2x = c
    b2 = rnd(1, 20) # new/different coefficient for 2nd x
    e = sprintf("%s%dx %s %dx = %d", n, a, op1, b2, c)
    } else if (f == 3) {
    # more complex: ax op1 b op2 x = c
    op2 = rop() # 2nd random operator
    e = sprintf("%s%dx %s %d %s x = %d", n, a, op1, b, op2, c)
    }

    # store equation in array if it doesn't already exist
    if (!(e in equ)) {
    equ[e] = 1 # mark element as reserved
    u++ # increment u for each unique equation
    }

    } while (u < 100)

    # print seed & equations
    printf("SEED: %d\n\n", SEED)
    for (j in equ) printf("%03d. %s\n", ++i, j)
    }

    function rop() { return substr("+-*/", rnd(1, 4), 1) }

    function rnd(min, max) { return int(rand() * (max - min + 1)) + min }

    # eof

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to All on Sun Dec 8 11:02:55 2024
    final iteration: family/work/time-constraints/etc

    earnest thanks to all (bonus points: Janis Papanagnou)

    # algebra.awk - Michael Sanders 2024
    #
    # invocation: awk -f algebra.awk -v SEED=$RANDOM > solve.txt
    #
    # generates unique algebraic equations in 3 forms...
    #
    # ax + b = c
    # ax + bx = c
    # ax + b + x = c
    #
    # where...
    #
    # x is the variable (solve for x)
    # a, b, & c are constants (numbers)
    #
    # operators: + addition, - subtraction, * multiplication, / division
    #
    # notes...
    #
    # - not all equations will be pedantically/academically proper
    # - SEED is optional & can be reused
    # - post improvements in comp.lang.awk
    #
    # further reading: https://en.wikipedia.org/wiki/Algebra

    BEGIN {

    # seed random number generator
    if (SEED+0 != SEED) SEED = 1; srand(SEED)

    g = 100 # number of unique equations to generate
    p = length(g) # uniform padding for serial number

    do {
    a = rnd(1, 20) # random value for x coefficient
    b = rnd(1, 99) # random value for b constant
    c = rnd(1, 500) # random value for c constant
    n = (rnd(1, 2) == 1) ? "-" : "" # random negative for x coefficient
    f = rnd(1, 3) # random equation form
    op1 = rop() # 1st random operator

    if (f == 1) {
    # simple equation: ax op1 b = c
    e = sprintf("%s%dx %s %d = %d", n, a, op1, b, c)
    } else if (f == 2) {
    # medium complexity: ax op1 b2x = c
    b2 = rnd(1, 20) # new/different coefficient for 2nd x
    e = sprintf("%s%dx %s %dx = %d", n, a, op1, b2, c)
    } else if (f == 3) {
    # more complex: ax op1 b op2 x = c
    op2 = rop() # 2nd random operator
    while (op2 == op1) op2 = rop() # hacky...
    e = sprintf("%s%dx %s %d %s x = %d", n, a, op1, b, op2, c)
    }

    # store equation in array if it doesn't already exist and is valid
    if (!(e in equ)) {
    equ[e] = 1 # mark element as reserved
    u++ # increment u for each unique equation
    }

    } while (u < g)

    printf("SEED: %d\n\n", SEED) # print seed & equations in blocks of 10
    for (j in equ) printf("%0" p "d. %s%s", ++i, j, (i % 10 == 0) ? "\n\n" : "\n")

    }

    function rop() { return substr("+-*/", rnd(1, 4), 1) }

    function rnd(min, max) { return int(rand() * (max - min + 1)) + min }

    # eof

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Mike Sanders on Sun Dec 8 15:15:55 2024
    On 08.12.2024 07:40, Mike Sanders wrote:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    [snip]

    See downthread, tell me what you think please kind sir...

    I see three new posts from you, all with variants/evolutions of
    your program it seems. - Which one shall I have a look into?

    (You know, since many/most of my suggestions aren't reflected
    in all those versions I don't want to bother or bore you with
    repetitions of my suggestions, and therefore I'm not sure what
    kind of feedback you actually want. - I think it's certainly
    better to ask others here for their opinions on your code and
    on the algorithms, which would [potentially] provide you with
    different views that may also match more with yours.)

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Sanders@21:1/5 to Janis Papanagnou on Mon Dec 9 16:43:42 2024
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    (You know, since many/most of my suggestions aren't reflected
    in all those versions I don't want to bother or bore you with
    repetitions of my suggestions, and therefore I'm not sure what
    kind of feedback you actually want. - I think it's certainly
    better to ask others here for their opinions on your code and
    on the algorithms, which would [potentially] provide you with
    different views that may also match more with yours.)

    Janis, just thanking for your time & input. Its true that I
    always consider the input others provide but also always go
    my own way. Only bound to my own thinking. Keeps things
    interesting for me. Here, its about moving quickly, testing
    ideas & seeing what works & what doesnt. Could even lead me
    to new, heretofore ways of looking at life.

    Feedback is whatever you think, like the thoughtful words
    you've written above.

    Bottom-line: No worries, its all good. =)

    --
    :wq
    Mike Sanders

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Janis Papanagnou@21:1/5 to Mike Sanders on Mon Dec 9 21:10:51 2024
    On 09.12.2024 17:43, Mike Sanders wrote:
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    (You know, since many/most of my suggestions aren't reflected
    in all those versions I don't want to bother or bore you with
    repetitions of my suggestions, and therefore I'm not sure what
    kind of feedback you actually want. - I think it's certainly
    better to ask others here for their opinions on your code and
    on the algorithms, which would [potentially] provide you with
    different views that may also match more with yours.)

    Janis, just thanking for your time & input. Its true that I
    always consider the input others provide but also always go
    my own way. [...]

    That's fine. (No offense or anything taken.)

    It makes just no sense for me to invest more time, and that's
    all I wanted to say, since (in your previous post) you seem to
    have asked me personally what I think about some of the newer
    versions of your program.


    Bottom-line: No worries, its all good. =)

    Janis

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)