http://www.categories.acsl.org/wiki/api.php?action=feedcontributions&user=Marc+Brown&feedformat=atomACSL Category Descriptions - User contributions [en]2021-01-24T12:53:54ZUser contributionsMediaWiki 1.26.3http://www.categories.acsl.org/wiki/index.php?title=Bit-String_Flicking&diff=624Bit-String Flicking2019-01-10T01:35:33Z<p>Marc Brown: /* Problem 1 */</p>
<hr />
<div><br />
Bit strings (strings of binary digits) are frequently manipulated bit-by-bit using the logical operators '''not''', '''and''', '''or''', and '''xor'''. Bits strings are manipulated as a unit using '''shift''' and '''circulate''' operators. The bits on the left are called the ''most significant bits'' and those on the right are the ''least significant bits''. <br />
<br />
Most high-level languages (e.g., Python, Java, C++), support bit-string operations. Programmers typically use bit strings to maintain a set of flags. Suppose that a program supports 8 options, each of which can be either “on” or “off”. One could maintain this information using an array of size 8, or one could use a single variable (if it is internally stored using at least 8 bits or 1 byte, which is usually the case) and represent each option with a single bit. In addition to saving space, the program is often cleaner if a single variable is involved rather than an array. Bits strings are often used to maintain a set where values are either in the set or not. Shifting of bits is also used to multiply or divide by powers of 2.<br />
<br />
Mastering this topic is essential for systems programming, programming in assembly language, optimizing code, and hardware design.<br />
<br />
== Operators==<br />
<br />
=== Bitwise Operators ===<br />
<br />
The logical operators are '''not''' (~ or $\neg$), '''and''' (&), '''or''' (|), and '''xor''' ($\oplus$). These operators should be familiar to ACSL students from the [[Boolean Algebra]] and [[Digital Electronics]] categories.<br />
<br />
* '''not''' is a unary operator that performs logical negation on each bit. Bits that are 0 become 1, and those that are 1 become 0. For example: ~101110 has a value of 010001.<br />
<br />
* '''and''' is a binary operator that performs the logical '''and''' of each bit in each of its operands. The '''and''' of two values is 1 only if both values are 1. For example, '''1011011 and 011001''' has a value of '''001001'''. The '''and''' function is often used to isolate the value of a bit in a bit-string or to clear the value of a bit in a bit-string.<br />
<br />
* '''or''' is a binary operator that performs the logical '''or''' of each bit in each of its operands. The '''or''' of two values is 1 only if one or both values are 1. For example, '''1011011 or 011001''' has a value of '''111011'''. The '''or''' function is often use to force the value of a bit in a bit-string to be 1, if it isn't already.<br />
<br />
* '''xor''' is a binary operator that performs the logical '''xor''' of each bit in each of its operands. The '''xor''' of two values is 1 if the values are different and 0 if they are the same. For example, 1011011 xor 011001 = 110010. The '''xor''' function is often used to change the value of a particular bit.<br />
<br />
All binary operators (and, or, or xor) must operate on bit-strings that are of<br />
the same length. If the operands are not the same<br />
length, the shorter one is padded with 0's on the left as needed. For <br />
example, '''11010 and 1110''' would have value of '''11010 and 01110 = 01010'''.<br />
<br />
The following table summarizes the operators:<br />
<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
! '''not''' <math>x</math><br />
!<math>x</math> '''and''' <math>y</math><br />
!<math>x</math> '''or''' <math>y</math><br />
!<math>x</math> '''xor''' <math>y</math><br />
|-<br />
!0<br />
!0<br />
| 1 <br />
| 0 <br />
| 0 <br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 0 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!1<br />
| 0 <br />
| 1 <br />
| 1 <br />
| 0<br />
|}<br />
<br />
=== Shift Operators ===<br />
<br />
Logical shifts (LSHIFT-x and RSHIFT-x) “ripple” the bit-string x positions in the indicated direction, either to the left or to the right. Bits shifted out are lost; zeros are shifted in at the other end. <br />
<br />
Circulates (RCIRC-x and LCIRC-x) “ripple” the bit string x positions in the indicated direction. As each bit is shifted out one end, it is shifted in at the other end. The effect of this is that the bits remain in the same order on the other side of the string.<br />
<br />
The size of a bit-string does not change with shifts, or circulates. If any bit strings are initially of different lengths, all shorter ones are padded with zeros in the left bits until all strings are of the same length. <br />
<br />
The following table gives some examples of these operations:<br />
<br />
::{| class="wikitable" style="text-align: right"<br />
|-<br />
!x<br />
!(LSHIFT-2 x)<br />
!(RSHIFT-3 x)<br />
!(LCIRC-3 x)<br />
!(RCIRC-1 x)<br />
|-<br />
!01101<br />
| 10100<br />
| 00001<br />
| 01011<br />
| 10110<br />
|-<br />
!10<br />
| 00<br />
| 00<br />
| 01<br />
| 01<br />
|-<br />
!1110<br />
| 1000<br />
| 0001<br />
| 0111<br />
| 0111<br />
|-<br />
!1011011<br />
| 1101100<br />
| 0001011<br />
| 1011101<br />
| 1101101<br />
|}<br />
<br />
=== Order of Precedence ===<br />
<br />
The order of precedence (from highest to lowest) is: NOT; SHIFT and CIRC; AND; XOR; and finally, OR. In other words, all unary operators are performed on a single operator first. Operators with equal precedence are evaluated left to right; all unary operators bind from right to left.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Evaluate the following expression: <br />
:(0101110 AND NOT 110110 OR (LSHIFT-3 101010))<br />
<br />
'''Solution:'''<br />
The expression evaluates as follows:<br />
:(0101110 AND '''001001''' OR (LSHIFT-3 101010))<br />
:('''001000''' OR (LSHIFT-3 101010))<br />
:(001000 OR '''010000''')<br />
:'''011000'''<br />
<br />
=== Problem 2 ===<br />
<br />
Evaluate the following expression: <br />
:(RSHIFT-1 (LCIRC-4 (RCIRC-2 01101))) <br />
<br />
'''Solution:'''<br />
The expression evaluates as follows, starting at the innermost parentheses:<br />
:(RCIRC-2 01101) => 01011<br />
:(LCIRC-4 01011) => 10101<br />
:(RSHIFT-1 10101) = 01010<br />
<br />
=== Problem 3 ===<br />
<br />
List all possible values of x (5 bits long) that solve the following equation.<br />
:(LSHIFT-1 (10110 XOR (RCIRC-3 x) AND 11011)) = 01100<br />
<br />
'''Solution:'''<br />
Since x is a string 5 bits long, represent it by abcde. (RCIRC-3 x) is cdeab which, when ANDed with 11011 gives cd0ab. This is XORed to 10110 to yield Cd1Ab (the capital letter is the NOT of its lower case).<br />
Now, (LSHIFT-1 Cd1Ab) = d1Ab0 which has a value of 01100, we must have d=0, A=1 (hence a=0), b=0. Thus, the solution must be in the form 00*0*, where * is an “I-don’t-care”. The four possible values of x are: 00000, 00001, 00100 and 00101.<br />
<br />
=== Problem 4 ===<br />
<br />
Evaluate the following expression:<br />
: ((RCIRC-14 (LCIRC-23 01101)) | (LSHIFT-1 10011) & (RSHIFT-2 10111))<br />
<br />
'''Solution:'''<br />
The problem can be rewritten as <br />
: A | B & C<br />
The AND has higher precedence than the OR. <br />
<br />
The evaluation of expression A can be done in a straightforward way: (LCIRC-23 01101) is the same as (LCIRC-3 01101) which has a value of 01011, and (RCIRC-14 01011) is the same as (RCIRC-4 01011) which has a value of 10110. Another strategy is to offset the left and right circulates. So, ((RCIRC-14 (LCIRC-23 01101)) has the same value as (LCIRC-9 01101), which has the same value as (LCIRC-4 01101) which is also 11010.<br />
<br />
Expressions B and C are pretty easy to evaluate:<br />
:B = (LSHIFT-1 10011) = 00110<br />
:C = (RSHIFT-2 10111) = 00101<br />
<br />
The expression becomes<br />
: A | B & C = 10110 | 00110 & 00101 = 10110 | 00100 = 10110<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/IeMsD3harrE</youtube><br />
| [https://youtu.be/IeMsD3harrE ''Bit String Flicking (Intro)'' ('''CalculusNguyenify''')]<br />
<br />
A great two-part tutorial on this ACSL category. Part 1 covers bitwise operations AND, OR, NOT, and XOR. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jbKw8oYJPs4</youtube><br />
| [https://youtu.be/jbKw8oYJPs4 ''Bit String Flicking Shifts and Circs'' ('''CalculusNguyenify''')]<br />
<br />
Part 2 covers logical shifts and circulate operations.<br />
<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/XNBcO25mgCw</youtube><br />
| [https://youtu.be/XNBcO25mgCw ''Bit String Flicking'' ('''Tangerine Code''')]<br />
<br />
Shows the solution to the problem: (RSHIFT-3 (LCIRC-2 (NOT 10110)))<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/8J9AdxU5CW8</youtube><br />
| [https://youtu.be/8J9AdxU5CW8 ''Bit String Flicking by Ravi Yeluru'' ('''hemsra''')]<br />
<br />
Walks through two problems from the Junior Division.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/aa_lQ8gft60</youtube><br />
| [https://youtu.be/aa_lQ8gft60 ''ACSL BitString Flicking Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Solves a handful of problems given in previous years at the Intermediate Division level.<br />
<br />
|}<br />
<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Bit-String_Flicking&diff=619Bit-String Flicking2019-01-09T14:54:09Z<p>Marc Brown: /* Problem 1 */</p>
<hr />
<div><br />
Bit strings (strings of binary digits) are frequently manipulated bit-by-bit using the logical operators '''not''', '''and''', '''or''', and '''xor'''. Bits strings are manipulated as a unit using '''shift''' and '''circulate''' operators. The bits on the left are called the ''most significant bits'' and those on the right are the ''least significant bits''. <br />
<br />
Most high-level languages (e.g., Python, Java, C++), support bit-string operations. Programmers typically use bit strings to maintain a set of flags. Suppose that a program supports 8 options, each of which can be either “on” or “off”. One could maintain this information using an array of size 8, or one could use a single variable (if it is internally stored using at least 8 bits or 1 byte, which is usually the case) and represent each option with a single bit. In addition to saving space, the program is often cleaner if a single variable is involved rather than an array. Bits strings are often used to maintain a set where values are either in the set or not. Shifting of bits is also used to multiply or divide by powers of 2.<br />
<br />
Mastering this topic is essential for systems programming, programming in assembly language, optimizing code, and hardware design.<br />
<br />
== Operators==<br />
<br />
=== Bitwise Operators ===<br />
<br />
The logical operators are '''not''' (~ or $\neg$), '''and''' (&), '''or''' (|), and '''xor''' ($\oplus$). These operators should be familiar to ACSL students from the [[Boolean Algebra]] and [[Digital Electronics]] categories.<br />
<br />
* '''not''' is a unary operator that performs logical negation on each bit. Bits that are 0 become 1, and those that are 1 become 0. For example: ~101110 has a value of 010001.<br />
<br />
* '''and''' is a binary operator that performs the logical '''and''' of each bit in each of its operands. The '''and''' of two values is 1 only if both values are 1. For example, '''1011011 and 011001''' has a value of '''001001'''. The '''and''' function is often used to isolate the value of a bit in a bit-string or to clear the value of a bit in a bit-string.<br />
<br />
* '''or''' is a binary operator that performs the logical '''or''' of each bit in each of its operands. The '''or''' of two values is 1 only if one or both values are 1. For example, '''1011011 or 011001''' has a value of '''111011'''. The '''or''' function is often use to force the value of a bit in a bit-string to be 1, if it isn't already.<br />
<br />
* '''xor''' is a binary operator that performs the logical '''xor''' of each bit in each of its operands. The '''xor''' of two values is 1 if the values are different and 0 if they are the same. For example, 1011011 xor 011001 = 110010. The '''xor''' function is often used to change the value of a particular bit.<br />
<br />
All binary operators (and, or, or xor) must operate on bit-strings that are of<br />
the same length. If the operands are not the same<br />
length, the shorter one is padded with 0's on the left as needed. For <br />
example, '''11010 and 1110''' would have value of '''11010 and 01110 = 01010'''.<br />
<br />
The following table summarizes the operators:<br />
<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
! '''not''' <math>x</math><br />
!<math>x</math> '''and''' <math>y</math><br />
!<math>x</math> '''or''' <math>y</math><br />
!<math>x</math> '''xor''' <math>y</math><br />
|-<br />
!0<br />
!0<br />
| 1 <br />
| 0 <br />
| 0 <br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 0 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!1<br />
| 0 <br />
| 1 <br />
| 1 <br />
| o<br />
|}<br />
<br />
=== Shift Operators ===<br />
<br />
Logical shifts (LSHIFT-x and RSHIFT-x) “ripple” the bit-string x positions in the indicated direction, either to the left or to the right. Bits shifted out are lost; zeros are shifted in at the other end. <br />
<br />
Circulates (RCIRC-x and LCIRC-x) “ripple” the bit string x positions in the indicated direction. As each bit is shifted out one end, it is shifted in at the other end. The effect of this is that the bits remain in the same order on the other side of the string.<br />
<br />
The size of a bit-string does not change with shifts, or circulates. If any bit strings are initially of different lengths, all shorter ones are padded with zeros in the left bits until all strings are of the same length. <br />
<br />
The following table gives some examples of these operations:<br />
<br />
::{| class="wikitable" style="text-align: right"<br />
|-<br />
!x<br />
!(LSHIFT-2 x)<br />
!(RSHIFT-3 x)<br />
!(LCIRC-3 x)<br />
!(RCIRC-1 x)<br />
|-<br />
!01101<br />
| 10100<br />
| 00001<br />
| 01011<br />
| 10110<br />
|-<br />
!10<br />
| 00<br />
| 00<br />
| 01<br />
| 01<br />
|-<br />
!1110<br />
| 1000<br />
| 0001<br />
| 0111<br />
| 0111<br />
|-<br />
!1011011<br />
| 1101100<br />
| 0001011<br />
| 1011101<br />
| 1101101<br />
|}<br />
<br />
=== Order of Precedence ===<br />
<br />
The order of precedence (from highest to lowest) is: NOT; SHIFT and CIRC; AND; XOR; and finally, OR. In other words, all unary operators are performed on a single operator first. Operators with equal precedence are evaluated left to right; all unary operators bind from right to left.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Evaluate the following expression: <br />
:(0101110 AND NOT 110110 OR (LSHIFT-2 101010))<br />
<br />
'''Solution:'''<br />
The expression evaluates as follows:<br />
:(0101110 AND '''001001''' OR (LSHIFT-2 101010))<br />
:('''001000''' OR (LSHIFT-2 101010))<br />
:(001000 OR '''010000''')<br />
:'''011000'''<br />
<br />
=== Problem 2 ===<br />
<br />
Evaluate the following expression: <br />
:(RSHIFT-1 (LCIRC-4 (RCIRC-2 01101))) <br />
<br />
'''Solution:'''<br />
The expression evaluates as follows, starting at the innermost parentheses:<br />
:(RCIRC-2 01101) => 01011<br />
:(LCIRC-4 01011) => 10101<br />
:(RSHIFT-1 10101) = 01010<br />
<br />
=== Problem 3 ===<br />
<br />
List all possible values of x (5 bits long) that solve the following equation.<br />
:(LSHIFT-1 (10110 XOR (RCIRC-3 x) AND 11011)) = 01100<br />
<br />
'''Solution:'''<br />
Since x is a string 5 bits long, represent it by abcde. (RCIRC-3 x) is cdeab which, when ANDed with 11011 gives cd0ab. This is XORed to 10110 to yield Cd1Ab (the capital letter is the NOT of its lower case).<br />
Now, (LSHIFT-1 Cd1Ab) = d1Ab0 which has a value of 01100, we must have d=0, A=1 (hence a=0), b=0. Thus, the solution must be in the form 00*0*, where * is an “I-don’t-care”. The four possible values of x are: 00000, 00001, 00100 and 00101.<br />
<br />
=== Problem 4 ===<br />
<br />
Evaluate the following expression:<br />
: ((RCIRC-14 (LCIRC-23 01101)) | (LSHIFT-1 10011) & (RSHIFT-2 10111))<br />
<br />
'''Solution:'''<br />
The problem can be rewritten as <br />
: A | B & C<br />
The AND has higher precedence than the OR. <br />
<br />
The evaluation of expression A can be done in a straightforward way: (LCIRC-23 01101) is the same as (LCIRC-3 01101) which has a value of 01011, and (RCIRC-14 01011) is the same as (RCIRC-4 01011) which has a value of 10110. Another strategy is to offset the left and right circulates. So, ((RCIRC-14 (LCIRC-23 01101)) has the same value as (LCIRC-9 01101), which has the same value as (LCIRC-4 01101) which is also 11010.<br />
<br />
Expressions B and C are pretty easy to evaluate:<br />
:B = (LSHIFT-1 10011) = 00110<br />
:C = (RSHIFT-2 10111) = 00101<br />
<br />
The expression becomes<br />
: A | B & C = 10110 | 00110 & 00101 = 10110 | 00100 = 10110<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/IeMsD3harrE</youtube><br />
| [https://youtu.be/IeMsD3harrE ''Bit String Flicking (Intro)'' ('''CalculusNguyenify''')]<br />
<br />
A great two-part tutorial on this ACSL category. Part 1 covers bitwise operations AND, OR, NOT, and XOR. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jbKw8oYJPs4</youtube><br />
| [https://youtu.be/jbKw8oYJPs4 ''Bit String Flicking Shifts and Circs'' ('''CalculusNguyenify''')]<br />
<br />
Part 2 covers logical shifts and circulate operations.<br />
<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/XNBcO25mgCw</youtube><br />
| [https://youtu.be/XNBcO25mgCw ''Bit String Flicking'' ('''Tangerine Code''')]<br />
<br />
Shows the solution to the problem: (RSHIFT-3 (LCIRC-2 (NOT 10110)))<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/8J9AdxU5CW8</youtube><br />
| [https://youtu.be/8J9AdxU5CW8 ''Bit String Flicking by Ravi Yeluru'' ('''hemsra''')]<br />
<br />
Walks through two problems from the Junior Division.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/aa_lQ8gft60</youtube><br />
| [https://youtu.be/aa_lQ8gft60 ''ACSL BitString Flicking Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Solves a handful of problems given in previous years at the Intermediate Division level.<br />
<br />
|}<br />
<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Bit-String_Flicking&diff=618Bit-String Flicking2019-01-09T14:54:06Z<p>Marc Brown: /* Problem 1 */</p>
<hr />
<div><br />
Bit strings (strings of binary digits) are frequently manipulated bit-by-bit using the logical operators '''not''', '''and''', '''or''', and '''xor'''. Bits strings are manipulated as a unit using '''shift''' and '''circulate''' operators. The bits on the left are called the ''most significant bits'' and those on the right are the ''least significant bits''. <br />
<br />
Most high-level languages (e.g., Python, Java, C++), support bit-string operations. Programmers typically use bit strings to maintain a set of flags. Suppose that a program supports 8 options, each of which can be either “on” or “off”. One could maintain this information using an array of size 8, or one could use a single variable (if it is internally stored using at least 8 bits or 1 byte, which is usually the case) and represent each option with a single bit. In addition to saving space, the program is often cleaner if a single variable is involved rather than an array. Bits strings are often used to maintain a set where values are either in the set or not. Shifting of bits is also used to multiply or divide by powers of 2.<br />
<br />
Mastering this topic is essential for systems programming, programming in assembly language, optimizing code, and hardware design.<br />
<br />
== Operators==<br />
<br />
=== Bitwise Operators ===<br />
<br />
The logical operators are '''not''' (~ or $\neg$), '''and''' (&), '''or''' (|), and '''xor''' ($\oplus$). These operators should be familiar to ACSL students from the [[Boolean Algebra]] and [[Digital Electronics]] categories.<br />
<br />
* '''not''' is a unary operator that performs logical negation on each bit. Bits that are 0 become 1, and those that are 1 become 0. For example: ~101110 has a value of 010001.<br />
<br />
* '''and''' is a binary operator that performs the logical '''and''' of each bit in each of its operands. The '''and''' of two values is 1 only if both values are 1. For example, '''1011011 and 011001''' has a value of '''001001'''. The '''and''' function is often used to isolate the value of a bit in a bit-string or to clear the value of a bit in a bit-string.<br />
<br />
* '''or''' is a binary operator that performs the logical '''or''' of each bit in each of its operands. The '''or''' of two values is 1 only if one or both values are 1. For example, '''1011011 or 011001''' has a value of '''111011'''. The '''or''' function is often use to force the value of a bit in a bit-string to be 1, if it isn't already.<br />
<br />
* '''xor''' is a binary operator that performs the logical '''xor''' of each bit in each of its operands. The '''xor''' of two values is 1 if the values are different and 0 if they are the same. For example, 1011011 xor 011001 = 110010. The '''xor''' function is often used to change the value of a particular bit.<br />
<br />
All binary operators (and, or, or xor) must operate on bit-strings that are of<br />
the same length. If the operands are not the same<br />
length, the shorter one is padded with 0's on the left as needed. For <br />
example, '''11010 and 1110''' would have value of '''11010 and 01110 = 01010'''.<br />
<br />
The following table summarizes the operators:<br />
<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
! '''not''' <math>x</math><br />
!<math>x</math> '''and''' <math>y</math><br />
!<math>x</math> '''or''' <math>y</math><br />
!<math>x</math> '''xor''' <math>y</math><br />
|-<br />
!0<br />
!0<br />
| 1 <br />
| 0 <br />
| 0 <br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 0 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!1<br />
| 0 <br />
| 1 <br />
| 1 <br />
| o<br />
|}<br />
<br />
=== Shift Operators ===<br />
<br />
Logical shifts (LSHIFT-x and RSHIFT-x) “ripple” the bit-string x positions in the indicated direction, either to the left or to the right. Bits shifted out are lost; zeros are shifted in at the other end. <br />
<br />
Circulates (RCIRC-x and LCIRC-x) “ripple” the bit string x positions in the indicated direction. As each bit is shifted out one end, it is shifted in at the other end. The effect of this is that the bits remain in the same order on the other side of the string.<br />
<br />
The size of a bit-string does not change with shifts, or circulates. If any bit strings are initially of different lengths, all shorter ones are padded with zeros in the left bits until all strings are of the same length. <br />
<br />
The following table gives some examples of these operations:<br />
<br />
::{| class="wikitable" style="text-align: right"<br />
|-<br />
!x<br />
!(LSHIFT-2 x)<br />
!(RSHIFT-3 x)<br />
!(LCIRC-3 x)<br />
!(RCIRC-1 x)<br />
|-<br />
!01101<br />
| 10100<br />
| 00001<br />
| 01011<br />
| 10110<br />
|-<br />
!10<br />
| 00<br />
| 00<br />
| 01<br />
| 01<br />
|-<br />
!1110<br />
| 1000<br />
| 0001<br />
| 0111<br />
| 0111<br />
|-<br />
!1011011<br />
| 1101100<br />
| 0001011<br />
| 1011101<br />
| 1101101<br />
|}<br />
<br />
=== Order of Precedence ===<br />
<br />
The order of precedence (from highest to lowest) is: NOT; SHIFT and CIRC; AND; XOR; and finally, OR. In other words, all unary operators are performed on a single operator first. Operators with equal precedence are evaluated left to right; all unary operators bind from right to left.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Evaluate the following expression: <br />
:(0101110 AND NOT 110110 OR (LSHIFT-2 101010))<br />
<br />
'''Solution:'''<br />
The expression evaluates as follows:<br />
:(0101110 AND '''001001''' OR (LSHIFT-2 101010))<br />
:('''001000''' OR (LSHIFT-2 101010))<br />
:(001000 OR '''010000''')<br />
:'''011000'''<br />
<br />
=== Problem 2 ===<br />
<br />
Evaluate the following expression: <br />
:(RSHIFT-1 (LCIRC-4 (RCIRC-2 01101))) <br />
<br />
'''Solution:'''<br />
The expression evaluates as follows, starting at the innermost parentheses:<br />
:(RCIRC-2 01101) => 01011<br />
:(LCIRC-4 01011) => 10101<br />
:(RSHIFT-1 10101) = 01010<br />
<br />
=== Problem 3 ===<br />
<br />
List all possible values of x (5 bits long) that solve the following equation.<br />
:(LSHIFT-1 (10110 XOR (RCIRC-3 x) AND 11011)) = 01100<br />
<br />
'''Solution:'''<br />
Since x is a string 5 bits long, represent it by abcde. (RCIRC-3 x) is cdeab which, when ANDed with 11011 gives cd0ab. This is XORed to 10110 to yield Cd1Ab (the capital letter is the NOT of its lower case).<br />
Now, (LSHIFT-1 Cd1Ab) = d1Ab0 which has a value of 01100, we must have d=0, A=1 (hence a=0), b=0. Thus, the solution must be in the form 00*0*, where * is an “I-don’t-care”. The four possible values of x are: 00000, 00001, 00100 and 00101.<br />
<br />
=== Problem 4 ===<br />
<br />
Evaluate the following expression:<br />
: ((RCIRC-14 (LCIRC-23 01101)) | (LSHIFT-1 10011) & (RSHIFT-2 10111))<br />
<br />
'''Solution:'''<br />
The problem can be rewritten as <br />
: A | B & C<br />
The AND has higher precedence than the OR. <br />
<br />
The evaluation of expression A can be done in a straightforward way: (LCIRC-23 01101) is the same as (LCIRC-3 01101) which has a value of 01011, and (RCIRC-14 01011) is the same as (RCIRC-4 01011) which has a value of 10110. Another strategy is to offset the left and right circulates. So, ((RCIRC-14 (LCIRC-23 01101)) has the same value as (LCIRC-9 01101), which has the same value as (LCIRC-4 01101) which is also 11010.<br />
<br />
Expressions B and C are pretty easy to evaluate:<br />
:B = (LSHIFT-1 10011) = 00110<br />
:C = (RSHIFT-2 10111) = 00101<br />
<br />
The expression becomes<br />
: A | B & C = 10110 | 00110 & 00101 = 10110 | 00100 = 10110<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/IeMsD3harrE</youtube><br />
| [https://youtu.be/IeMsD3harrE ''Bit String Flicking (Intro)'' ('''CalculusNguyenify''')]<br />
<br />
A great two-part tutorial on this ACSL category. Part 1 covers bitwise operations AND, OR, NOT, and XOR. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jbKw8oYJPs4</youtube><br />
| [https://youtu.be/jbKw8oYJPs4 ''Bit String Flicking Shifts and Circs'' ('''CalculusNguyenify''')]<br />
<br />
Part 2 covers logical shifts and circulate operations.<br />
<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/XNBcO25mgCw</youtube><br />
| [https://youtu.be/XNBcO25mgCw ''Bit String Flicking'' ('''Tangerine Code''')]<br />
<br />
Shows the solution to the problem: (RSHIFT-3 (LCIRC-2 (NOT 10110)))<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/8J9AdxU5CW8</youtube><br />
| [https://youtu.be/8J9AdxU5CW8 ''Bit String Flicking by Ravi Yeluru'' ('''hemsra''')]<br />
<br />
Walks through two problems from the Junior Division.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/aa_lQ8gft60</youtube><br />
| [https://youtu.be/aa_lQ8gft60 ''ACSL BitString Flicking Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Solves a handful of problems given in previous years at the Intermediate Division level.<br />
<br />
|}<br />
<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Bit-String_Flicking&diff=617Bit-String Flicking2019-01-09T08:30:44Z<p>Marc Brown: /* Bitwise Operators */</p>
<hr />
<div><br />
Bit strings (strings of binary digits) are frequently manipulated bit-by-bit using the logical operators '''not''', '''and''', '''or''', and '''xor'''. Bits strings are manipulated as a unit using '''shift''' and '''circulate''' operators. The bits on the left are called the ''most significant bits'' and those on the right are the ''least significant bits''. <br />
<br />
Most high-level languages (e.g., Python, Java, C++), support bit-string operations. Programmers typically use bit strings to maintain a set of flags. Suppose that a program supports 8 options, each of which can be either “on” or “off”. One could maintain this information using an array of size 8, or one could use a single variable (if it is internally stored using at least 8 bits or 1 byte, which is usually the case) and represent each option with a single bit. In addition to saving space, the program is often cleaner if a single variable is involved rather than an array. Bits strings are often used to maintain a set where values are either in the set or not. Shifting of bits is also used to multiply or divide by powers of 2.<br />
<br />
Mastering this topic is essential for systems programming, programming in assembly language, optimizing code, and hardware design.<br />
<br />
== Operators==<br />
<br />
=== Bitwise Operators ===<br />
<br />
The logical operators are '''not''' (~ or $\neg$), '''and''' (&), '''or''' (|), and '''xor''' ($\oplus$). These operators should be familiar to ACSL students from the [[Boolean Algebra]] and [[Digital Electronics]] categories.<br />
<br />
* '''not''' is a unary operator that performs logical negation on each bit. Bits that are 0 become 1, and those that are 1 become 0. For example: ~101110 has a value of 010001.<br />
<br />
* '''and''' is a binary operator that performs the logical '''and''' of each bit in each of its operands. The '''and''' of two values is 1 only if both values are 1. For example, '''1011011 and 011001''' has a value of '''001001'''. The '''and''' function is often used to isolate the value of a bit in a bit-string or to clear the value of a bit in a bit-string.<br />
<br />
* '''or''' is a binary operator that performs the logical '''or''' of each bit in each of its operands. The '''or''' of two values is 1 only if one or both values are 1. For example, '''1011011 or 011001''' has a value of '''111011'''. The '''or''' function is often use to force the value of a bit in a bit-string to be 1, if it isn't already.<br />
<br />
* '''xor''' is a binary operator that performs the logical '''xor''' of each bit in each of its operands. The '''xor''' of two values is 1 if the values are different and 0 if they are the same. For example, 1011011 xor 011001 = 110010. The '''xor''' function is often used to change the value of a particular bit.<br />
<br />
All binary operators (and, or, or xor) must operate on bit-strings that are of<br />
the same length. If the operands are not the same<br />
length, the shorter one is padded with 0's on the left as needed. For <br />
example, '''11010 and 1110''' would have value of '''11010 and 01110 = 01010'''.<br />
<br />
The following table summarizes the operators:<br />
<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
! '''not''' <math>x</math><br />
!<math>x</math> '''and''' <math>y</math><br />
!<math>x</math> '''or''' <math>y</math><br />
!<math>x</math> '''xor''' <math>y</math><br />
|-<br />
!0<br />
!0<br />
| 1 <br />
| 0 <br />
| 0 <br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 0 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!1<br />
| 0 <br />
| 1 <br />
| 1 <br />
| o<br />
|}<br />
<br />
=== Shift Operators ===<br />
<br />
Logical shifts (LSHIFT-x and RSHIFT-x) “ripple” the bit-string x positions in the indicated direction, either to the left or to the right. Bits shifted out are lost; zeros are shifted in at the other end. <br />
<br />
Circulates (RCIRC-x and LCIRC-x) “ripple” the bit string x positions in the indicated direction. As each bit is shifted out one end, it is shifted in at the other end. The effect of this is that the bits remain in the same order on the other side of the string.<br />
<br />
The size of a bit-string does not change with shifts, or circulates. If any bit strings are initially of different lengths, all shorter ones are padded with zeros in the left bits until all strings are of the same length. <br />
<br />
The following table gives some examples of these operations:<br />
<br />
::{| class="wikitable" style="text-align: right"<br />
|-<br />
!x<br />
!(LSHIFT-2 x)<br />
!(RSHIFT-3 x)<br />
!(LCIRC-3 x)<br />
!(RCIRC-1 x)<br />
|-<br />
!01101<br />
| 10100<br />
| 00001<br />
| 01011<br />
| 10110<br />
|-<br />
!10<br />
| 00<br />
| 00<br />
| 01<br />
| 01<br />
|-<br />
!1110<br />
| 1000<br />
| 0001<br />
| 0111<br />
| 0111<br />
|-<br />
!1011011<br />
| 1101100<br />
| 0001011<br />
| 1011101<br />
| 1101101<br />
|}<br />
<br />
=== Order of Precedence ===<br />
<br />
The order of precedence (from highest to lowest) is: NOT; SHIFT and CIRC; AND; XOR; and finally, OR. In other words, all unary operators are performed on a single operator first. Operators with equal precedence are evaluated left to right; all unary operators bind from right to left.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Evaluate the following expression: <br />
:(0101110 AND NOT 110110 OR (LSHIFT-2 101010))<br />
<br />
'''Solution:'''<br />
The expression evaluates as follows:<br />
:(0101110 AND '''001001''' OR (LSHIFT-2 101010))<br />
:('''001000''' OR (LSHIFT-3 101010))<br />
:(001000 OR '''010000''')<br />
:'''011000'''<br />
<br />
=== Problem 2 ===<br />
<br />
Evaluate the following expression: <br />
:(RSHIFT-1 (LCIRC-4 (RCIRC-2 01101))) <br />
<br />
'''Solution:'''<br />
The expression evaluates as follows, starting at the innermost parentheses:<br />
:(RCIRC-2 01101) => 01011<br />
:(LCIRC-4 01011) => 10101<br />
:(RSHIFT-1 10101) = 01010<br />
<br />
=== Problem 3 ===<br />
<br />
List all possible values of x (5 bits long) that solve the following equation.<br />
:(LSHIFT-1 (10110 XOR (RCIRC-3 x) AND 11011)) = 01100<br />
<br />
'''Solution:'''<br />
Since x is a string 5 bits long, represent it by abcde. (RCIRC-3 x) is cdeab which, when ANDed with 11011 gives cd0ab. This is XORed to 10110 to yield Cd1Ab (the capital letter is the NOT of its lower case).<br />
Now, (LSHIFT-1 Cd1Ab) = d1Ab0 which has a value of 01100, we must have d=0, A=1 (hence a=0), b=0. Thus, the solution must be in the form 00*0*, where * is an “I-don’t-care”. The four possible values of x are: 00000, 00001, 00100 and 00101.<br />
<br />
=== Problem 4 ===<br />
<br />
Evaluate the following expression:<br />
: ((RCIRC-14 (LCIRC-23 01101)) | (LSHIFT-1 10011) & (RSHIFT-2 10111))<br />
<br />
'''Solution:'''<br />
The problem can be rewritten as <br />
: A | B & C<br />
The AND has higher precedence than the OR. <br />
<br />
The evaluation of expression A can be done in a straightforward way: (LCIRC-23 01101) is the same as (LCIRC-3 01101) which has a value of 01011, and (RCIRC-14 01011) is the same as (RCIRC-4 01011) which has a value of 10110. Another strategy is to offset the left and right circulates. So, ((RCIRC-14 (LCIRC-23 01101)) has the same value as (LCIRC-9 01101), which has the same value as (LCIRC-4 01101) which is also 11010.<br />
<br />
Expressions B and C are pretty easy to evaluate:<br />
:B = (LSHIFT-1 10011) = 00110<br />
:C = (RSHIFT-2 10111) = 00101<br />
<br />
The expression becomes<br />
: A | B & C = 10110 | 00110 & 00101 = 10110 | 00100 = 10110<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/IeMsD3harrE</youtube><br />
| [https://youtu.be/IeMsD3harrE ''Bit String Flicking (Intro)'' ('''CalculusNguyenify''')]<br />
<br />
A great two-part tutorial on this ACSL category. Part 1 covers bitwise operations AND, OR, NOT, and XOR. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jbKw8oYJPs4</youtube><br />
| [https://youtu.be/jbKw8oYJPs4 ''Bit String Flicking Shifts and Circs'' ('''CalculusNguyenify''')]<br />
<br />
Part 2 covers logical shifts and circulate operations.<br />
<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/XNBcO25mgCw</youtube><br />
| [https://youtu.be/XNBcO25mgCw ''Bit String Flicking'' ('''Tangerine Code''')]<br />
<br />
Shows the solution to the problem: (RSHIFT-3 (LCIRC-2 (NOT 10110)))<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/8J9AdxU5CW8</youtube><br />
| [https://youtu.be/8J9AdxU5CW8 ''Bit String Flicking by Ravi Yeluru'' ('''hemsra''')]<br />
<br />
Walks through two problems from the Junior Division.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/aa_lQ8gft60</youtube><br />
| [https://youtu.be/aa_lQ8gft60 ''ACSL BitString Flicking Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Solves a handful of problems given in previous years at the Intermediate Division level.<br />
<br />
|}<br />
<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=LISP&diff=616LISP2019-01-09T08:29:07Z<p>Marc Brown: /* Basic Functions (SET, SETQ, EVAL, ATOM) */</p>
<hr />
<div>LISP is one of the simplest computer languages in terms of syntax and semantics, and also one of the most powerful. It was developed in the mid-1950’s by John McCarthy at M.I.T. as a “LISt Processing language.” It has been historically used for virtually all Artificial Intelligence programs and is often the environment of choice for applications which require a powerful interactive working environment. LISP presents a very different way to think about programming from the “algorithmic” languages, such as Python, C++, and Java.<br />
<br />
== Syntax ==<br />
<br />
As its name implies, the basis of LISP is a list. One constructs a list by enumerating elements inside a pair of parentheses. For example, here is a list with four elements (the second element is also a list):<br />
<br />
:<code>(23 (this is easy) hello 821)</code><br />
<br />
The elements in the list, which are not lists, are called “atoms.” For example, the atoms in the list above are: 23, ‘this, ‘hello, 821, ‘easy, and ‘is. Literals are identified with a single leading quote. Everything in LISP is either an atom or a list (but not both). The only exception is “NIL,” which is both an atom and a list. It can also be written as “()” – a pair of parentheses with nothing inside.<br />
<br />
All statements in LISP are function calls with the following syntax: (function arg1 arg2 arg3 … argn). To evaluate a LISP statement, each of the arguments (possibly functions themselves) are evaluated, and then the function is invoked with the arguments. For example, (MULT (ADD 2 3) (ADD 1 4 2)) has a value of 35, since (ADD 2 3) has a value of 5, (ADD 1 4 2) has a value of 7, and (MULT 5 7) has a value of 35. Some functions have an arbitrary number of arguments; others require a fixed number. All statements return a value, which is either an atom or a list. <br />
<br />
== Basic Functions (SET, SETQ, EVAL, ATOM) ==<br />
<br />
We may assign values to variables using the function SET. For example, the statement (SET ’test 6) would have a value of a 6, and (more importantly, however) would also cause the atom ‘test to be bound to the atom 6. The function SETQ is the same as SET, but it causes LISP to act as if the first argument was quoted. <br />
Observe the following examples:<br />
<br />
:{| class="wikitable" style="text-align: left"<br />
!Statement || Value || Comment <br />
|-<br />
|(SET ’a ( MULT 2 3))<br />
|6<br />
|a is an atom with a vaue of 6<br />
|-<br />
|(SET ’a ’(MULT 2 3))<br />
|(MULT 2 3)<br />
|a is a list with 3 elements<br />
|-<br />
|(SET ’b ’a)<br />
|a<br />
|b is an atom with a value of the character a<br />
|-<br />
|(SET ’c a)<br />
|(MULT 2 3)<br />
|c is a list with 3 elements<br />
|-<br />
|(SETQ EX (ADD 3 (MULT 2 5)))<br />
|13<br />
|The variable EX has a value of 13<br />
|-<br />
|(SETQ VOWELS ’(A E I O U))<br />
|(A E I O U)<br />
|VOWELS is a list of 5 elements<br />
|}<br />
<br />
The function EVAL returns the value of its argument, after it has been evaluated. For example, (SETQ z ’(ADD 2 3)) has a value of the list (ADD 2 3); the function (EVAL ’z) has a value of (ADD 2 3); the function (EVAL z) has a value of 5 (but the binding of the atom z has not changed). In this last example, you can think of z being “resolved” twice: once because it is an argument to a function and LISP evaluates all arguments to functions before the function is invoked, and once when the function EVAL is invoked to resolve arguments. The function ATOM can be used to determine whether an item is an atom or a list. It returns either "true", or "NIL" for false. Consider the following examples:<br />
<br />
:{| class="wikitable" style="text-align: left"<br />
!Statement || Value || Comment <br />
|-<br />
|(SETQ p '(ADD 1 2 3 4))<br />
|(ADD 1 2 3 4)<br />
|p is a list with 5 elements<br />
|-<br />
|(ATOM 'p)<br />
|true<br />
|The argument to ATOM is the atom p<br />
|-<br />
|(ATOM p)<br />
|NIL<br />
|Because p is not quoted, it is evaluated to the 5-element list.<br />
|-<br />
|(EVAL p)<br />
|10<br />
|The argument to EVAL is the value of p; the value of p is 10. <br />
|}<br />
<br />
== List Functions (CAR, CDR, CONS, REVERSE)==<br />
<br />
The two most famous LISP functions are CAR and CDR (pronounced: could-er), named after registers of a now long-forgotten IBM machine on which LISP was first developed. The function (CAR x) returns the first item of the list x (and x must be a list or an error will occur); (CDR x) returns the list without its first element (again, x must be a list). The function CONS takes two arguments, of which the second must be a list. It returns a list which is composed by placing the first argument as the first element in the second argument’s list. The function REVERSE returns a list which is its arguments in reverse order. <br />
<br />
The CAR and CDR functions are used extensively to grab specific elements of a list or sublist, that there's a shorthand for this: (CADR x) is the same as (CAR (CDR x)), which retrieves the second element of the list x; (CAADDAR x) is a shorthand for (CAR (CAR (CDR (CDR (CAR x))))), and so on.<br />
<br />
The following examples illustrate the use of CAR, CDR, CONS, and REVERSE: <br />
<br />
:{| class="wikitable" style="text-align: left"<br />
!Statement || Value<br />
|-<br />
|(CAR ’(This is a list))<br />
|This<br />
|-<br />
|(CDR ’(This is a list)))<br />
|(is a list)<br />
|-<br />
|(CONS 'red '(white blue))<br />
|(red white blue)<br />
|-<br />
|(SETQ z (CONS '(red white blue) (CDR ’(This is a list)))))<br />
|((red white blue) is a list)<br />
|-<br />
|(REVERSE z)<br />
|(list a is (red white blue))<br />
|-<br />
|(CDDAR z)<br />
|(blue)<br />
|}<br />
<br />
== Arithmetic Functions (ADD, MULT, ...)==<br />
<br />
As you have probably already figured out, the function ADD simply summed its arguments. We’ll also be using the following arithmetic functions:<br />
<br />
:{| class="wikitable" style="text-align: left"<br />
!'''Function''' || '''Result'''<br />
|-<br />
|(ADD x1 x2 …)<br />
|sum of all arguments<br />
|-<br />
|(SUB a b)<br />
|a-b<br />
|-<br />
|(MULT x1 x2 …)<br />
|product of all arguments<br />
|-<br />
|(DIV a b)<br />
|a/b<br />
|-<br />
|(SQUARE a)<br />
|a*a<br />
|-<br />
|(EXP a n)<br />
|a<sup>n</sup><br />
|-<br />
|(EQ a b)<br />
|true if a and b are equal, NIL otherwise<br />
|-<br />
|(POS a)<br />
|true if a is positive, NIL otherwise<br />
|-<br />
|(NEG a)<br />
|true if a is negative, NIL otherwise<br />
|-<br />
|}<br />
<br />
Functions ADD, SUB, MULT, and DIV can be written as their common mathematical symbols, +, -, *, and /. Here are some examples of these functions:<br />
<br />
:{| class="wikitable"<br />
!'''Statement''' || '''Value'''<br />
|-<br />
|(ADD (EXP 2 3) (SUB 4 1) (DIV 54 4))<br />
|24.5<br />
|-<br />
|(- (* 3 2) (- 12 (+ 1 2 1)))<br />
| -2<br />
|-<br />
|(ADD (SQUARE 3) (SQUARE 4))<br />
|25<br />
|}<br />
<br />
== User-defined Functions ==<br />
<br />
LISP also allows us to create our own functions using the DEF function. (We will sometimes use DEFUN rather than DEF, as it is a bit more standard terminology.) For example,<br />
(DEF SECOND (args) (CAR (CDR args)))<br />
defines a new function called SECOND which operates on a single parameter named “args”. SECOND will take the CDR of the parameter and then the CAR of that result. So, for example:<br />
(SECOND ’(a b c d e))<br />
would first CDR the list to give (b c d e), and then CAR that value returning the single character “b”. Consider the following program fragment:<br />
:(SETQ X ’(a c s l))<br />
:(DEF WHAT(args) (CONS args (REVERSE (CDR args))))<br />
:(DEF SECOND(args) (CONS (CAR (CDR args)) NIL))<br />
<br />
The following chart illustrates the use of the user-defined functions WHAT and SECOND:<br />
<br />
:{| class="wikitable"<br />
!Statement || Value<br />
|-<br />
|(WHAT X) || ((a c s l) l s c)<br />
|-<br />
|(SECOND X) || (c)<br />
|-<br />
|(SECOND (WHAT X)) || (l)<br />
|-<br />
|(WHAT (SECOND X)) || ((c))<br />
|}<br />
<br />
== Online Interpreters ==<br />
<br />
There are many online LISP interpreters available on the Internet. The one that ACSL uses for testing its programs is CLISP that is accessible from [https://www.jdoodle.com/execute-clisp-online JDoodle]. This interpreter is nice because it is quite peppy in running programs, and functions are not case sensitive. So, <code>(CAR (CDR x))</code> is legal as is <code>(car (cdr x))</code> One drawback of this interpreter is the print function changes lowercase input into uppercase. <br />
<br />
== Sample Problems ==<br />
<br />
Questions from this topic will typically present a line of LISP code or a short sequence of statements and ask what is the value of the (final) statement.<br />
<br />
=== Problem 1 ===<br />
<br />
Evaluate the following expression. <code>(MULT (ADD 6 5 0) (MULT 5 1 2 2) (DIV 9 (SUB 2 5)))</code><br />
<br />
'''Solution:'''<br />
(MULT (ADD 6 5 0) (MULT 5 1 2 2) (DIV 6 (SUB 2 5)))<br />
(MULT 11 20 (DIV 6 -3))<br />
(MULT 11 20 -2)<br />
-440<br />
<br />
=== Problem 2 ===<br />
<br />
Evaluate the following expression: <code>(CDR ’((2 (3))(4 (5 6) 7)))</code><br />
<br />
'''Solution:'''<br />
The CDR function takes the first element of its parameter (which is assumed to be a list) and returns the list with the first element removed. The first element of the list is (2 (3)) and the list without this element is<br />
((4 (5 6) 7)), a list with one element.<br />
<br />
=== Problem 3 ===<br />
<br />
Consider the following program fragment:<br />
<syntaxhighlight><br />
(SETQ X ’(RI VA FL CA TX))<br />
(CAR (CDR (REVERSE X)))<br />
</syntaxhighlight><br />
What is the value of the CAR expression? <br />
<br />
'''Solution:'''<br />
The first statement binds variable X to the list ‘(RI VA FL CA TX).<br />
The REVERSE of this list is ‘(TX CA FL VA RI)<br />
whose CDR is ‘(CA FL VA RI). The CAR of this list is just the atom CA (without the quote).<br />
<br />
<!-- <br />
<br />
Too scary of a sample problem! --marc 9/3/2018<br />
<br />
=== Problem 4 ===<br />
<br />
Given the function definitions for HY and FY as follows:<br />
(DEFUN HY(PARM) (REVERSE (CDR PARM)))<br />
(DEFUN FY(PARM) (CAR (HY (CDR PARM))))<br />
What is the value of the following?<br />
(FY ’(DO RE (MI FA) SO))<br />
<br />
'''Solution:'''<br />
To evaluate (FY ’(DO RE (MI FA) SO)), we must evaluate<br />
(CAR (HY (CDR ’(DO RE (MI FA) SO)))).<br />
Thus, HY is invoked with <br />
PARM = ’(RE (MI FA) SO), and we evaluate<br />
(REVERSE (CDR ’(RE (MI FA) SO)))<br />
This has a value of (SO (MI FA)) which is returned to FY. FY now takes the CAR of this which is SO (without the quotes).<br />
--><br />
<br />
== Video Resources ==<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jWFgmE279eQ</youtube><br />
| [https://youtu.be/jWFgmE279eQ ''LISP very gentle intro'' ('''CalculusNguyenify''')]<br />
<br />
A very gentle introduction to the LISP category, covering the LISP syntax and the basic operators, SETQ, ADD, SUB, MULT, and DIV.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/mRpbbss48sw</youtube><br />
| [https://youtu.be/mRpbbss48sw ''LISP Basics (for ACSL)'' ('''Tangerine Code''')]<br />
<br />
Explains the LISP operators CAR, CDR, and REVERSE, in the context of solving an ACSL All-Star Contest problem.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/50wj_f51kBM</youtube><br />
| [https://youtu.be/50wj_f51kBM ''LISP Basics (for ACSL)'' ('''Tangerine Code''')]<br />
<br />
Completes the problem that was started in the above video. <br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=File:Graph_sample3.svg&diff=615File:Graph sample3.svg2019-01-09T08:27:18Z<p>Marc Brown: Marc Brown uploaded a new version of File:Graph sample3.svg</p>
<hr />
<div></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Digital_Electronics&diff=614Digital Electronics2018-10-27T13:08:13Z<p>Marc Brown: /* Online Tools */</p>
<hr />
<div>A digital circuit is constructed from logic gates. Each logic gate performs a function of boolean logic based on its inputs, such as AND or OR. <br />
Each circuit can be represented as a Boolean Algebra expression; <br />
this topic is an extension of the topic of [[Boolean Algebra]], which includes <br />
a thorough description of truth tables and simplifying expressions. <br />
<br />
= Definitions =<br />
<br />
The following table illustrates all logic gates. For each logic gate, the<br />
table shows the equivalent Boolean algebra expression and truth table.<br />
<br />
{| class="wikitable" style="text-align: left"<br />
|-<br />
!'''NAME'''<br />
!'''GRAPHICAL SYMBOL'''<br />
!'''ALGEBRAIC EXPRESSION'''<br />
!'''TRUTH TABLE'''<br />
|-<br />
!'''BUFFER'''<br />
| [[File:Buffer-gate-en.svg|128px]]<br />
| X = A<br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
| 0 || 0<br />
|-<br />
| 1 || 1<br />
|}<br />
|-<br />
!'''NOT'''<br />
| [[File:Not-gate-en.svg|128px]]<br />
| X = <math>\overline{A}</math> or <math>\neg A</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || X<br />
|-<br />
| 0 || 1<br />
|-<br />
| 1 || 0<br />
|}<br />
|-<br />
!'''AND'''<br />
| |[[File:And-gate.png|128px]]<br />
| X = <math>AB</math> or <math>A \cdot B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="1" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NAND'''<br />
| [[File:Nand-gate-en.svg|128px]]<br />
| X = <math>\overline{AB}</math> or <math>\overline{A\cdot B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''OR'''<br />
| [[File:Or-gate-en.svg|128px]]<br />
| X = <math>A+B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NOR'''<br />
| [[File:Nor-gate-en.svg|128px]]<br />
| X = <math>\overline{A+B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XOR'''<br />
|[[File:Xor-gate-en.svg|128px]]<br />
| X = <math>A \oplus B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XNOR'''<br />
| [[File:Xnor-gate-en.svg|128px]]<br />
| X = <math>\overline{A \oplus B} \text{ or } A \odot B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|}<br />
<br />
Note that there is some ambiguity in the conversion from a diagram to a circuit. For example, is <math>\overline{A+B}</math> an OR gate followed by a NOT gate, or smply<br />
a NOT gate.<br />
<br />
=Online Tools=<br />
<br />
The [http://www.cburch.com/logisim/index.html Logisim] application is a wonderful tool<br />
for exploring this topic.<br />
Logisim is free to download and use; among its many features is support to automatically draw<br />
a circuit from a Boolean Algebra expression; to simulate the circuit with arbitrary inputs;<br />
and to complete a truth table for the circuit. From the application, you can import the circuit corresponding to the [[#Sample_Problem_1|Sample Problem 1]] <br />
from the file located at [http://www.acsl.org/misc/wiki-digital-electronics-sample1.circ http://www.acsl.org/misc/wiki-digital-electronics-sample1.circ].<br />
There are many YouTube videos that show how to use the Logisim application; including a very nice [https://www.youtube.com/watch?v=cMz7wyY_PxE 4 minute tutorial].<br />
<br />
Logisim contains many <br />
additional advanced features that are beyond<br />
the scope of ACSL problems.<br />
<br />
=Sample Problems =<br />
<br />
== Sample Problem 1 ==<br />
<br />
Find all ordered triplets (A, B, C) which make the following circuit FALSE:<br />
<br />
::[[File:NotABorC.svg|200px]]<br />
<br />
'''Solution:'''<br />
<br />
One approach to solving this problem is to reason about that inputs and outputs are necessary at each gate. For the circuit to be FALSE, both inputs to the file OR gate must be false. Thus, input C must be FALSE, and the output of the NAND gate must also be false. The NAND gate is false only when both of its inputs are TRUE; thus, inputs A and B must both be TRUE. The final answer is (TRUE, TRUE, FALSE), or (1, 1, 0).<br />
<br />
Another approach to solving this problem is to translate the circuit into a Boolean Algebra expression and simplify <br />
the expression using the laws of Boolean Algebra. This circuit translates to the Boolean expression <math>\overline{AB}+C</math>. <br />
To find when this is FALSE we can equivalently find when the <math>\overline{\overline{AB}+C}</math> is TRUE. <br />
The expression becomes <math>\overline{\overline{AB}}\cdot \overline{C}</math> after applying DeMorgan’s Law. The double NOT over the AB expression<br />
cancels out, to become <math>AB\overline{C}</math>. The AND of 3 terms is TRUE when each term is TRUE, or A=1, B=1 and C=0.<br />
<br />
== Sample Problem 2 ==<br />
<br />
How many ordered 4-tuples (A, B, C, D) make the following circuit TRUE?<br />
<br />
::[[File:circuit-sample2.svg |400px]]<br />
<br />
'''Solution:'''<br />
<br />
We'll use a truth table to solve this problem. The rows in the truth table will correspond to all possible inputs - 16 in this case, since there are 4 inputs. The output columns will be the output of each gate, other than the NOT gates. The diagram below labels each of the gates; it's useful to keep the column straight when working the truth table.<br />
<br />
::[[File:circuit-sample2-labels.svg |300px]]<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="4" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="5" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
!rowspan="2" | A<br />
!rowspan="2" | B<br />
!rowspan="2" | C<br />
!rowspan="2" | D<br />
! p<br />
! q<br />
! r<br />
! s<br />
! t<br />
|-<br />
!<math>\overline{C+D}</math><br />
!<math>p+\overline{B}</math><br />
!<math>\overline{A}B</math><br />
!<math>r \oplus q</math><br />
!<math>s \oplus p</math><br />
|-<br />
|0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|0 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 1 || 0 || 0 || 1 || 1 || 1 || 0 || 1<br />
|-<br />
|0 || 1 || 0 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 0 || 0 || 1 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|1 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 1 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 1 || 0 || 1 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 0 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 1 || 0 || 0 || 0 || 0 || 0<br />
|}<br />
<br />
From the truth table, there are 10 rows where the final output is TRUE.<br />
<br />
= Video Resources =<br />
<br />
==ACSL Advisors==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gxil9VyGTtE</youtube><br />
| [https://youtu.be/gxil9VyGTtE ''Digital Electronics -1'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Introduces the AND, OR, and NOT gates, and works through a couple of simple circuits.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/m7-wa5ca_G8</youtube><br />
| [https://youtu.be/m7-wa5ca_G8 Digital Electronics -2'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression <math>(\overline{A}+B)(\overline{B+C})</math>.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/Eckd5UlJmB4</youtube><br />
| [https://youtu.be/Eckd5UlJmB4 ''Digital Electronics Boolean Algebra'' ('''Tangerine Code''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression<br />
<math>\overline{(A+B)}(B+C)</math>. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/JJL6DsVCpHo</youtube><br />
| [https://youtu.be/JJL6DsVCpHo ''ACSL Digital Electronics Worksheet Sample'' ('''misterminich''')]<br />
<br />
Solves a handful of ACSL problems.<br />
|}<br />
<br />
<br />
==Other Videos==<br />
<br />
The topic of Digital Electronics is fundamental in Computer Science and there are many videos on YouTube that teach this subject. We found the following videos to be<br />
nice introductions to digital logic gates. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/s2MI_NgKD98</youtube><br />
| [https://youtu.be/s2MI_NgKD98 ''Digital Electronics Basics'' ('''Beginning Electronics''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/z9s8A8oBe7g</youtube><br />
| [https://youtu.be/z9s8A8oBe7g ''Logic Gate Expressions'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/TLl4E3IV6Z0</youtube><br />
| [https://youtu.be/TLl4E3IV6Z0 ''Logic Gate Combinations'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/eroqZpbKrhc</youtube><br />
| [https://youtu.be/eroqZpbKrhc ''Determining the truth table and logic statement'' ('''Anna does some physics''')]<br />
Uses a truth table to find the inputs that make the circuit <math>\not(A+B)+(AB)</math> true using a truth table.<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Digital_Electronics&diff=613Digital Electronics2018-10-27T12:40:56Z<p>Marc Brown: /* Online Tools */</p>
<hr />
<div>A digital circuit is constructed from logic gates. Each logic gate performs a function of boolean logic based on its inputs, such as AND or OR. <br />
Each circuit can be represented as a Boolean Algebra expression; <br />
this topic is an extension of the topic of [[Boolean Algebra]], which includes <br />
a thorough description of truth tables and simplifying expressions. <br />
<br />
= Definitions =<br />
<br />
The following table illustrates all logic gates. For each logic gate, the<br />
table shows the equivalent Boolean algebra expression and truth table.<br />
<br />
{| class="wikitable" style="text-align: left"<br />
|-<br />
!'''NAME'''<br />
!'''GRAPHICAL SYMBOL'''<br />
!'''ALGEBRAIC EXPRESSION'''<br />
!'''TRUTH TABLE'''<br />
|-<br />
!'''BUFFER'''<br />
| [[File:Buffer-gate-en.svg|128px]]<br />
| X = A<br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
| 0 || 0<br />
|-<br />
| 1 || 1<br />
|}<br />
|-<br />
!'''NOT'''<br />
| [[File:Not-gate-en.svg|128px]]<br />
| X = <math>\overline{A}</math> or <math>\neg A</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || X<br />
|-<br />
| 0 || 1<br />
|-<br />
| 1 || 0<br />
|}<br />
|-<br />
!'''AND'''<br />
| |[[File:And-gate.png|128px]]<br />
| X = <math>AB</math> or <math>A \cdot B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="1" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NAND'''<br />
| [[File:Nand-gate-en.svg|128px]]<br />
| X = <math>\overline{AB}</math> or <math>\overline{A\cdot B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''OR'''<br />
| [[File:Or-gate-en.svg|128px]]<br />
| X = <math>A+B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NOR'''<br />
| [[File:Nor-gate-en.svg|128px]]<br />
| X = <math>\overline{A+B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XOR'''<br />
|[[File:Xor-gate-en.svg|128px]]<br />
| X = <math>A \oplus B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XNOR'''<br />
| [[File:Xnor-gate-en.svg|128px]]<br />
| X = <math>\overline{A \oplus B} \text{ or } A \odot B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|}<br />
<br />
Note that there is some ambiguity in the conversion from a diagram to a circuit. For example, is <math>\overline{A+B}</math> an OR gate followed by a NOT gate, or smply<br />
a NOT gate.<br />
<br />
=Online Tools=<br />
<br />
The [http://www.cburch.com/logisim/index.html Logisim] application is a wonderful tool<br />
for exploring this topic.<br />
Logisim is free to download and use; among its many features is support to automatically draw<br />
a circuit from a Boolean Algebra expression; to simulate the circuit with arbitrary inputs;<br />
and to complete a truth table for the circuit. From the application, you can import the circuit corresponding to the [[#Sample_Problem_1|Sample Problem 1]] <br />
from the file located at [http://www.acsl.org/misc/wiki-digital-electronics-sample1.circ http://www.acsl.org/misc/wiki-digital-electronics-sample1.circ]<br />
Logisim contains many <br />
additional advanced features that are beyond<br />
the scope of ACSL problems.<br />
<br />
=Sample Problems =<br />
<br />
== Sample Problem 1 ==<br />
<br />
Find all ordered triplets (A, B, C) which make the following circuit FALSE:<br />
<br />
::[[File:NotABorC.svg|200px]]<br />
<br />
'''Solution:'''<br />
<br />
One approach to solving this problem is to reason about that inputs and outputs are necessary at each gate. For the circuit to be FALSE, both inputs to the file OR gate must be false. Thus, input C must be FALSE, and the output of the NAND gate must also be false. The NAND gate is false only when both of its inputs are TRUE; thus, inputs A and B must both be TRUE. The final answer is (TRUE, TRUE, FALSE), or (1, 1, 0).<br />
<br />
Another approach to solving this problem is to translate the circuit into a Boolean Algebra expression and simplify <br />
the expression using the laws of Boolean Algebra. This circuit translates to the Boolean expression <math>\overline{AB}+C</math>. <br />
To find when this is FALSE we can equivalently find when the <math>\overline{\overline{AB}+C}</math> is TRUE. <br />
The expression becomes <math>\overline{\overline{AB}}\cdot \overline{C}</math> after applying DeMorgan’s Law. The double NOT over the AB expression<br />
cancels out, to become <math>AB\overline{C}</math>. The AND of 3 terms is TRUE when each term is TRUE, or A=1, B=1 and C=0.<br />
<br />
== Sample Problem 2 ==<br />
<br />
How many ordered 4-tuples (A, B, C, D) make the following circuit TRUE?<br />
<br />
::[[File:circuit-sample2.svg |400px]]<br />
<br />
'''Solution:'''<br />
<br />
We'll use a truth table to solve this problem. The rows in the truth table will correspond to all possible inputs - 16 in this case, since there are 4 inputs. The output columns will be the output of each gate, other than the NOT gates. The diagram below labels each of the gates; it's useful to keep the column straight when working the truth table.<br />
<br />
::[[File:circuit-sample2-labels.svg |300px]]<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="4" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="5" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
!rowspan="2" | A<br />
!rowspan="2" | B<br />
!rowspan="2" | C<br />
!rowspan="2" | D<br />
! p<br />
! q<br />
! r<br />
! s<br />
! t<br />
|-<br />
!<math>\overline{C+D}</math><br />
!<math>p+\overline{B}</math><br />
!<math>\overline{A}B</math><br />
!<math>r \oplus q</math><br />
!<math>s \oplus p</math><br />
|-<br />
|0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|0 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 1 || 0 || 0 || 1 || 1 || 1 || 0 || 1<br />
|-<br />
|0 || 1 || 0 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 0 || 0 || 1 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|1 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 1 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 1 || 0 || 1 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 0 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 1 || 0 || 0 || 0 || 0 || 0<br />
|}<br />
<br />
From the truth table, there are 10 rows where the final output is TRUE.<br />
<br />
= Video Resources =<br />
<br />
==ACSL Advisors==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gxil9VyGTtE</youtube><br />
| [https://youtu.be/gxil9VyGTtE ''Digital Electronics -1'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Introduces the AND, OR, and NOT gates, and works through a couple of simple circuits.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/m7-wa5ca_G8</youtube><br />
| [https://youtu.be/m7-wa5ca_G8 Digital Electronics -2'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression <math>(\overline{A}+B)(\overline{B+C})</math>.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/Eckd5UlJmB4</youtube><br />
| [https://youtu.be/Eckd5UlJmB4 ''Digital Electronics Boolean Algebra'' ('''Tangerine Code''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression<br />
<math>\overline{(A+B)}(B+C)</math>. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/JJL6DsVCpHo</youtube><br />
| [https://youtu.be/JJL6DsVCpHo ''ACSL Digital Electronics Worksheet Sample'' ('''misterminich''')]<br />
<br />
Solves a handful of ACSL problems.<br />
|}<br />
<br />
<br />
==Other Videos==<br />
<br />
The topic of Digital Electronics is fundamental in Computer Science and there are many videos on YouTube that teach this subject. We found the following videos to be<br />
nice introductions to digital logic gates. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/s2MI_NgKD98</youtube><br />
| [https://youtu.be/s2MI_NgKD98 ''Digital Electronics Basics'' ('''Beginning Electronics''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/z9s8A8oBe7g</youtube><br />
| [https://youtu.be/z9s8A8oBe7g ''Logic Gate Expressions'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/TLl4E3IV6Z0</youtube><br />
| [https://youtu.be/TLl4E3IV6Z0 ''Logic Gate Combinations'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/eroqZpbKrhc</youtube><br />
| [https://youtu.be/eroqZpbKrhc ''Determining the truth table and logic statement'' ('''Anna does some physics''')]<br />
Uses a truth table to find the inputs that make the circuit <math>\not(A+B)+(AB)</math> true using a truth table.<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Digital_Electronics&diff=612Digital Electronics2018-10-27T12:40:09Z<p>Marc Brown: /* Online Tools */</p>
<hr />
<div>A digital circuit is constructed from logic gates. Each logic gate performs a function of boolean logic based on its inputs, such as AND or OR. <br />
Each circuit can be represented as a Boolean Algebra expression; <br />
this topic is an extension of the topic of [[Boolean Algebra]], which includes <br />
a thorough description of truth tables and simplifying expressions. <br />
<br />
= Definitions =<br />
<br />
The following table illustrates all logic gates. For each logic gate, the<br />
table shows the equivalent Boolean algebra expression and truth table.<br />
<br />
{| class="wikitable" style="text-align: left"<br />
|-<br />
!'''NAME'''<br />
!'''GRAPHICAL SYMBOL'''<br />
!'''ALGEBRAIC EXPRESSION'''<br />
!'''TRUTH TABLE'''<br />
|-<br />
!'''BUFFER'''<br />
| [[File:Buffer-gate-en.svg|128px]]<br />
| X = A<br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
| 0 || 0<br />
|-<br />
| 1 || 1<br />
|}<br />
|-<br />
!'''NOT'''<br />
| [[File:Not-gate-en.svg|128px]]<br />
| X = <math>\overline{A}</math> or <math>\neg A</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || X<br />
|-<br />
| 0 || 1<br />
|-<br />
| 1 || 0<br />
|}<br />
|-<br />
!'''AND'''<br />
| |[[File:And-gate.png|128px]]<br />
| X = <math>AB</math> or <math>A \cdot B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="1" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NAND'''<br />
| [[File:Nand-gate-en.svg|128px]]<br />
| X = <math>\overline{AB}</math> or <math>\overline{A\cdot B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''OR'''<br />
| [[File:Or-gate-en.svg|128px]]<br />
| X = <math>A+B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NOR'''<br />
| [[File:Nor-gate-en.svg|128px]]<br />
| X = <math>\overline{A+B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XOR'''<br />
|[[File:Xor-gate-en.svg|128px]]<br />
| X = <math>A \oplus B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XNOR'''<br />
| [[File:Xnor-gate-en.svg|128px]]<br />
| X = <math>\overline{A \oplus B} \text{ or } A \odot B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|}<br />
<br />
Note that there is some ambiguity in the conversion from a diagram to a circuit. For example, is <math>\overline{A+B}</math> an OR gate followed by a NOT gate, or smply<br />
a NOT gate.<br />
<br />
=Online Tools=<br />
<br />
The [http://www.cburch.com/logisim/index.html Logisim] application is a wonderful tool<br />
for exploring this topic.<br />
Logisim is free to download and use; among its many features is support to automatically draw<br />
a circuit from a Boolean Algebra expression; to simulate the circuit with arbitrary inputs;<br />
and to complete a truth table for the circuit. From the application, you can import the circuit corresponding to the [[#Sample_Problem_1|Sample Problem 1]] <br />
from [http://www.acsl.org/misc/wiki-digital-electronics-sample1.circ http://www.acsl.org/misc/wiki-digital-electronics-sample1.circ]<br />
There are many <br />
additional advanced features that are beyond<br />
the scope of ACSL problems.<br />
<br />
=Sample Problems =<br />
<br />
== Sample Problem 1 ==<br />
<br />
Find all ordered triplets (A, B, C) which make the following circuit FALSE:<br />
<br />
::[[File:NotABorC.svg|200px]]<br />
<br />
'''Solution:'''<br />
<br />
One approach to solving this problem is to reason about that inputs and outputs are necessary at each gate. For the circuit to be FALSE, both inputs to the file OR gate must be false. Thus, input C must be FALSE, and the output of the NAND gate must also be false. The NAND gate is false only when both of its inputs are TRUE; thus, inputs A and B must both be TRUE. The final answer is (TRUE, TRUE, FALSE), or (1, 1, 0).<br />
<br />
Another approach to solving this problem is to translate the circuit into a Boolean Algebra expression and simplify <br />
the expression using the laws of Boolean Algebra. This circuit translates to the Boolean expression <math>\overline{AB}+C</math>. <br />
To find when this is FALSE we can equivalently find when the <math>\overline{\overline{AB}+C}</math> is TRUE. <br />
The expression becomes <math>\overline{\overline{AB}}\cdot \overline{C}</math> after applying DeMorgan’s Law. The double NOT over the AB expression<br />
cancels out, to become <math>AB\overline{C}</math>. The AND of 3 terms is TRUE when each term is TRUE, or A=1, B=1 and C=0.<br />
<br />
== Sample Problem 2 ==<br />
<br />
How many ordered 4-tuples (A, B, C, D) make the following circuit TRUE?<br />
<br />
::[[File:circuit-sample2.svg |400px]]<br />
<br />
'''Solution:'''<br />
<br />
We'll use a truth table to solve this problem. The rows in the truth table will correspond to all possible inputs - 16 in this case, since there are 4 inputs. The output columns will be the output of each gate, other than the NOT gates. The diagram below labels each of the gates; it's useful to keep the column straight when working the truth table.<br />
<br />
::[[File:circuit-sample2-labels.svg |300px]]<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="4" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="5" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
!rowspan="2" | A<br />
!rowspan="2" | B<br />
!rowspan="2" | C<br />
!rowspan="2" | D<br />
! p<br />
! q<br />
! r<br />
! s<br />
! t<br />
|-<br />
!<math>\overline{C+D}</math><br />
!<math>p+\overline{B}</math><br />
!<math>\overline{A}B</math><br />
!<math>r \oplus q</math><br />
!<math>s \oplus p</math><br />
|-<br />
|0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|0 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 1 || 0 || 0 || 1 || 1 || 1 || 0 || 1<br />
|-<br />
|0 || 1 || 0 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 0 || 0 || 1 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|1 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 1 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 1 || 0 || 1 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 0 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 1 || 0 || 0 || 0 || 0 || 0<br />
|}<br />
<br />
From the truth table, there are 10 rows where the final output is TRUE.<br />
<br />
= Video Resources =<br />
<br />
==ACSL Advisors==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gxil9VyGTtE</youtube><br />
| [https://youtu.be/gxil9VyGTtE ''Digital Electronics -1'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Introduces the AND, OR, and NOT gates, and works through a couple of simple circuits.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/m7-wa5ca_G8</youtube><br />
| [https://youtu.be/m7-wa5ca_G8 Digital Electronics -2'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression <math>(\overline{A}+B)(\overline{B+C})</math>.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/Eckd5UlJmB4</youtube><br />
| [https://youtu.be/Eckd5UlJmB4 ''Digital Electronics Boolean Algebra'' ('''Tangerine Code''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression<br />
<math>\overline{(A+B)}(B+C)</math>. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/JJL6DsVCpHo</youtube><br />
| [https://youtu.be/JJL6DsVCpHo ''ACSL Digital Electronics Worksheet Sample'' ('''misterminich''')]<br />
<br />
Solves a handful of ACSL problems.<br />
|}<br />
<br />
<br />
==Other Videos==<br />
<br />
The topic of Digital Electronics is fundamental in Computer Science and there are many videos on YouTube that teach this subject. We found the following videos to be<br />
nice introductions to digital logic gates. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/s2MI_NgKD98</youtube><br />
| [https://youtu.be/s2MI_NgKD98 ''Digital Electronics Basics'' ('''Beginning Electronics''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/z9s8A8oBe7g</youtube><br />
| [https://youtu.be/z9s8A8oBe7g ''Logic Gate Expressions'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/TLl4E3IV6Z0</youtube><br />
| [https://youtu.be/TLl4E3IV6Z0 ''Logic Gate Combinations'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/eroqZpbKrhc</youtube><br />
| [https://youtu.be/eroqZpbKrhc ''Determining the truth table and logic statement'' ('''Anna does some physics''')]<br />
Uses a truth table to find the inputs that make the circuit <math>\not(A+B)+(AB)</math> true using a truth table.<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Digital_Electronics&diff=611Digital Electronics2018-10-27T12:20:51Z<p>Marc Brown: /* Online Resources */</p>
<hr />
<div>A digital circuit is constructed from logic gates. Each logic gate performs a function of boolean logic based on its inputs, such as AND or OR. <br />
Each circuit can be represented as a Boolean Algebra expression; <br />
this topic is an extension of the topic of [[Boolean Algebra]], which includes <br />
a thorough description of truth tables and simplifying expressions. <br />
<br />
= Definitions =<br />
<br />
The following table illustrates all logic gates. For each logic gate, the<br />
table shows the equivalent Boolean algebra expression and truth table.<br />
<br />
{| class="wikitable" style="text-align: left"<br />
|-<br />
!'''NAME'''<br />
!'''GRAPHICAL SYMBOL'''<br />
!'''ALGEBRAIC EXPRESSION'''<br />
!'''TRUTH TABLE'''<br />
|-<br />
!'''BUFFER'''<br />
| [[File:Buffer-gate-en.svg|128px]]<br />
| X = A<br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
| 0 || 0<br />
|-<br />
| 1 || 1<br />
|}<br />
|-<br />
!'''NOT'''<br />
| [[File:Not-gate-en.svg|128px]]<br />
| X = <math>\overline{A}</math> or <math>\neg A</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || X<br />
|-<br />
| 0 || 1<br />
|-<br />
| 1 || 0<br />
|}<br />
|-<br />
!'''AND'''<br />
| |[[File:And-gate.png|128px]]<br />
| X = <math>AB</math> or <math>A \cdot B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="1" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NAND'''<br />
| [[File:Nand-gate-en.svg|128px]]<br />
| X = <math>\overline{AB}</math> or <math>\overline{A\cdot B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''OR'''<br />
| [[File:Or-gate-en.svg|128px]]<br />
| X = <math>A+B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NOR'''<br />
| [[File:Nor-gate-en.svg|128px]]<br />
| X = <math>\overline{A+B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XOR'''<br />
|[[File:Xor-gate-en.svg|128px]]<br />
| X = <math>A \oplus B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XNOR'''<br />
| [[File:Xnor-gate-en.svg|128px]]<br />
| X = <math>\overline{A \oplus B} \text{ or } A \odot B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|}<br />
<br />
Note that there is some ambiguity in the conversion from a diagram to a circuit. For example, is <math>\overline{A+B}</math> an OR gate followed by a NOT gate, or smply<br />
a NOT gate.<br />
<br />
=Online Tools=<br />
<br />
The [http://www.cburch.com/logisim/index.html Logisim] application is a wonderful tool<br />
for exploring this topic.<br />
Logisim is free to download and use; among its many features is support to automatically draw<br />
a circuit from a Boolean Algebra expression; to simulate the circuit with arbitrary inputs;<br />
and to complete a truth table for the circuit. There are many <br />
additional advanced features that are beyond<br />
the scope of ACSL problems. Check it out!<br />
<br />
=Sample Problems =<br />
<br />
== Sample Problem 1 ==<br />
<br />
Find all ordered triplets (A, B, C) which make the following circuit FALSE:<br />
<br />
::[[File:NotABorC.svg|200px]]<br />
<br />
'''Solution:'''<br />
<br />
One approach to solving this problem is to reason about that inputs and outputs are necessary at each gate. For the circuit to be FALSE, both inputs to the file OR gate must be false. Thus, input C must be FALSE, and the output of the NAND gate must also be false. The NAND gate is false only when both of its inputs are TRUE; thus, inputs A and B must both be TRUE. The final answer is (TRUE, TRUE, FALSE), or (1, 1, 0).<br />
<br />
Another approach to solving this problem is to translate the circuit into a Boolean Algebra expression and simplify <br />
the expression using the laws of Boolean Algebra. This circuit translates to the Boolean expression <math>\overline{AB}+C</math>. <br />
To find when this is FALSE we can equivalently find when the <math>\overline{\overline{AB}+C}</math> is TRUE. <br />
The expression becomes <math>\overline{\overline{AB}}\cdot \overline{C}</math> after applying DeMorgan’s Law. The double NOT over the AB expression<br />
cancels out, to become <math>AB\overline{C}</math>. The AND of 3 terms is TRUE when each term is TRUE, or A=1, B=1 and C=0.<br />
<br />
== Sample Problem 2 ==<br />
<br />
How many ordered 4-tuples (A, B, C, D) make the following circuit TRUE?<br />
<br />
::[[File:circuit-sample2.svg |400px]]<br />
<br />
'''Solution:'''<br />
<br />
We'll use a truth table to solve this problem. The rows in the truth table will correspond to all possible inputs - 16 in this case, since there are 4 inputs. The output columns will be the output of each gate, other than the NOT gates. The diagram below labels each of the gates; it's useful to keep the column straight when working the truth table.<br />
<br />
::[[File:circuit-sample2-labels.svg |300px]]<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="4" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="5" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
!rowspan="2" | A<br />
!rowspan="2" | B<br />
!rowspan="2" | C<br />
!rowspan="2" | D<br />
! p<br />
! q<br />
! r<br />
! s<br />
! t<br />
|-<br />
!<math>\overline{C+D}</math><br />
!<math>p+\overline{B}</math><br />
!<math>\overline{A}B</math><br />
!<math>r \oplus q</math><br />
!<math>s \oplus p</math><br />
|-<br />
|0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|0 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 1 || 0 || 0 || 1 || 1 || 1 || 0 || 1<br />
|-<br />
|0 || 1 || 0 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 0 || 0 || 1 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|1 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 1 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 1 || 0 || 1 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 0 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 1 || 0 || 0 || 0 || 0 || 0<br />
|}<br />
<br />
From the truth table, there are 10 rows where the final output is TRUE.<br />
<br />
= Video Resources =<br />
<br />
==ACSL Advisors==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gxil9VyGTtE</youtube><br />
| [https://youtu.be/gxil9VyGTtE ''Digital Electronics -1'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Introduces the AND, OR, and NOT gates, and works through a couple of simple circuits.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/m7-wa5ca_G8</youtube><br />
| [https://youtu.be/m7-wa5ca_G8 Digital Electronics -2'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression <math>(\overline{A}+B)(\overline{B+C})</math>.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/Eckd5UlJmB4</youtube><br />
| [https://youtu.be/Eckd5UlJmB4 ''Digital Electronics Boolean Algebra'' ('''Tangerine Code''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression<br />
<math>\overline{(A+B)}(B+C)</math>. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/JJL6DsVCpHo</youtube><br />
| [https://youtu.be/JJL6DsVCpHo ''ACSL Digital Electronics Worksheet Sample'' ('''misterminich''')]<br />
<br />
Solves a handful of ACSL problems.<br />
|}<br />
<br />
<br />
==Other Videos==<br />
<br />
The topic of Digital Electronics is fundamental in Computer Science and there are many videos on YouTube that teach this subject. We found the following videos to be<br />
nice introductions to digital logic gates. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/s2MI_NgKD98</youtube><br />
| [https://youtu.be/s2MI_NgKD98 ''Digital Electronics Basics'' ('''Beginning Electronics''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/z9s8A8oBe7g</youtube><br />
| [https://youtu.be/z9s8A8oBe7g ''Logic Gate Expressions'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/TLl4E3IV6Z0</youtube><br />
| [https://youtu.be/TLl4E3IV6Z0 ''Logic Gate Combinations'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/eroqZpbKrhc</youtube><br />
| [https://youtu.be/eroqZpbKrhc ''Determining the truth table and logic statement'' ('''Anna does some physics''')]<br />
Uses a truth table to find the inputs that make the circuit <math>\not(A+B)+(AB)</math> true using a truth table.<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Digital_Electronics&diff=610Digital Electronics2018-10-27T12:18:45Z<p>Marc Brown: </p>
<hr />
<div>A digital circuit is constructed from logic gates. Each logic gate performs a function of boolean logic based on its inputs, such as AND or OR. <br />
Each circuit can be represented as a Boolean Algebra expression; <br />
this topic is an extension of the topic of [[Boolean Algebra]], which includes <br />
a thorough description of truth tables and simplifying expressions. <br />
<br />
= Definitions =<br />
<br />
The following table illustrates all logic gates. For each logic gate, the<br />
table shows the equivalent Boolean algebra expression and truth table.<br />
<br />
{| class="wikitable" style="text-align: left"<br />
|-<br />
!'''NAME'''<br />
!'''GRAPHICAL SYMBOL'''<br />
!'''ALGEBRAIC EXPRESSION'''<br />
!'''TRUTH TABLE'''<br />
|-<br />
!'''BUFFER'''<br />
| [[File:Buffer-gate-en.svg|128px]]<br />
| X = A<br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
| 0 || 0<br />
|-<br />
| 1 || 1<br />
|}<br />
|-<br />
!'''NOT'''<br />
| [[File:Not-gate-en.svg|128px]]<br />
| X = <math>\overline{A}</math> or <math>\neg A</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || X<br />
|-<br />
| 0 || 1<br />
|-<br />
| 1 || 0<br />
|}<br />
|-<br />
!'''AND'''<br />
| |[[File:And-gate.png|128px]]<br />
| X = <math>AB</math> or <math>A \cdot B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="1" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NAND'''<br />
| [[File:Nand-gate-en.svg|128px]]<br />
| X = <math>\overline{AB}</math> or <math>\overline{A\cdot B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''OR'''<br />
| [[File:Or-gate-en.svg|128px]]<br />
| X = <math>A+B</math> <br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|-<br />
!'''NOR'''<br />
| [[File:Nor-gate-en.svg|128px]]<br />
| X = <math>\overline{A+B}</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XOR'''<br />
|[[File:Xor-gate-en.svg|128px]]<br />
| X = <math>A \oplus B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 0<br />
|-<br />
| 0 || 1 || 1<br />
|-<br />
| 1 || 0 || 1<br />
|-<br />
| 1 || 1 || 0<br />
|}<br />
|-<br />
!'''XNOR'''<br />
| [[File:Xnor-gate-en.svg|128px]]<br />
| X = <math>\overline{A \oplus B} \text{ or } A \odot B</math><br />
|<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="2" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
! A || B || X<br />
|-<br />
| 0 || 0 || 1<br />
|-<br />
| 0 || 1 || 0<br />
|-<br />
| 1 || 0 || 0<br />
|-<br />
| 1 || 1 || 1<br />
|}<br />
|}<br />
<br />
Note that there is some ambiguity in the conversion from a diagram to a circuit. For example, is <math>\overline{A+B}</math> an OR gate followed by a NOT gate, or smply<br />
a NOT gate.<br />
<br />
=Online Resources=<br />
<br />
The [Logism http://www.cburch.com/logisim/index.html] application is a wonderful tool<br />
for exploring this topic.<br />
Logism is free to download and use; among its many features is support to automatically draw<br />
a circuit from a Boolean Algebra expression; to simulate the circuit with arbitrary inputs;<br />
and to complete a truth table for the circuit. There are many <br />
additional advanced features that are beyond<br />
the scope of ACSL problems. Check it out! <br />
<br />
=Sample Problems =<br />
<br />
== Sample Problem 1 ==<br />
<br />
Find all ordered triplets (A, B, C) which make the following circuit FALSE:<br />
<br />
::[[File:NotABorC.svg|200px]]<br />
<br />
'''Solution:'''<br />
<br />
One approach to solving this problem is to reason about that inputs and outputs are necessary at each gate. For the circuit to be FALSE, both inputs to the file OR gate must be false. Thus, input C must be FALSE, and the output of the NAND gate must also be false. The NAND gate is false only when both of its inputs are TRUE; thus, inputs A and B must both be TRUE. The final answer is (TRUE, TRUE, FALSE), or (1, 1, 0).<br />
<br />
Another approach to solving this problem is to translate the circuit into a Boolean Algebra expression and simplify <br />
the expression using the laws of Boolean Algebra. This circuit translates to the Boolean expression <math>\overline{AB}+C</math>. <br />
To find when this is FALSE we can equivalently find when the <math>\overline{\overline{AB}+C}</math> is TRUE. <br />
The expression becomes <math>\overline{\overline{AB}}\cdot \overline{C}</math> after applying DeMorgan’s Law. The double NOT over the AB expression<br />
cancels out, to become <math>AB\overline{C}</math>. The AND of 3 terms is TRUE when each term is TRUE, or A=1, B=1 and C=0.<br />
<br />
== Sample Problem 2 ==<br />
<br />
How many ordered 4-tuples (A, B, C, D) make the following circuit TRUE?<br />
<br />
::[[File:circuit-sample2.svg |400px]]<br />
<br />
'''Solution:'''<br />
<br />
We'll use a truth table to solve this problem. The rows in the truth table will correspond to all possible inputs - 16 in this case, since there are 4 inputs. The output columns will be the output of each gate, other than the NOT gates. The diagram below labels each of the gates; it's useful to keep the column straight when working the truth table.<br />
<br />
::[[File:circuit-sample2-labels.svg |300px]]<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|-<br />
|colspan="4" style="background-color: #cceeff; font-size: x-small" "|INPUT<br />
|colspan="5" style="background-color: #cceeff; font-size: x-small" "|OUTPUT<br />
|-<br />
!rowspan="2" | A<br />
!rowspan="2" | B<br />
!rowspan="2" | C<br />
!rowspan="2" | D<br />
! p<br />
! q<br />
! r<br />
! s<br />
! t<br />
|-<br />
!<math>\overline{C+D}</math><br />
!<math>p+\overline{B}</math><br />
!<math>\overline{A}B</math><br />
!<math>r \oplus q</math><br />
!<math>s \oplus p</math><br />
|-<br />
|0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|0 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|0 || 1 || 0 || 0 || 1 || 1 || 1 || 0 || 1<br />
|-<br />
|0 || 1 || 0 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 0 || 0 || 1 || 1 || 1 || 1<br />
|-<br />
|0 || 1 || 1 || 1 || 0 || 0 || 1 || 1 || 1<br />
|-<br />
|1 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 0 || 0 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 0 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 0 || 1 || 1 || 0 || 1 || 0 || 1 || 1<br />
|-<br />
|1 || 1 || 0 || 0 || 1 || 1 || 0 || 1 || 0<br />
|-<br />
|1 || 1 || 0 || 1 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 0 || 0 || 0 || 0 || 0 || 0<br />
|-<br />
|1 || 1 || 1 || 1 || 0 || 0 || 0 || 0 || 0<br />
|}<br />
<br />
From the truth table, there are 10 rows where the final output is TRUE.<br />
<br />
= Video Resources =<br />
<br />
==ACSL Advisors==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gxil9VyGTtE</youtube><br />
| [https://youtu.be/gxil9VyGTtE ''Digital Electronics -1'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Introduces the AND, OR, and NOT gates, and works through a couple of simple circuits.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/m7-wa5ca_G8</youtube><br />
| [https://youtu.be/m7-wa5ca_G8 Digital Electronics -2'' ('''Ravi Yeluru (hemsra)''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression <math>(\overline{A}+B)(\overline{B+C})</math>.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/Eckd5UlJmB4</youtube><br />
| [https://youtu.be/Eckd5UlJmB4 ''Digital Electronics Boolean Algebra'' ('''Tangerine Code''')]<br />
<br />
Solves a 3-gate circuit (the AND of an OR and a NOR) given by the Boolean expression<br />
<math>\overline{(A+B)}(B+C)</math>. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/JJL6DsVCpHo</youtube><br />
| [https://youtu.be/JJL6DsVCpHo ''ACSL Digital Electronics Worksheet Sample'' ('''misterminich''')]<br />
<br />
Solves a handful of ACSL problems.<br />
|}<br />
<br />
<br />
==Other Videos==<br />
<br />
The topic of Digital Electronics is fundamental in Computer Science and there are many videos on YouTube that teach this subject. We found the following videos to be<br />
nice introductions to digital logic gates. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/s2MI_NgKD98</youtube><br />
| [https://youtu.be/s2MI_NgKD98 ''Digital Electronics Basics'' ('''Beginning Electronics''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/z9s8A8oBe7g</youtube><br />
| [https://youtu.be/z9s8A8oBe7g ''Logic Gate Expressions'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/TLl4E3IV6Z0</youtube><br />
| [https://youtu.be/TLl4E3IV6Z0 ''Logic Gate Combinations'' ('''Kevin Drumm''')]<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/eroqZpbKrhc</youtube><br />
| [https://youtu.be/eroqZpbKrhc ''Determining the truth table and logic statement'' ('''Anna does some physics''')]<br />
Uses a truth table to find the inputs that make the circuit <math>\not(A+B)+(AB)</math> true using a truth table.<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Main_Page&diff=609Main Page2018-10-21T08:07:07Z<p>Marc Brown: </p>
<hr />
<div>Welcome to the wiki describing the topics covered in the short programs section of the [//www.acsl.org ACSL] contests.<br />
<br />
If you'd like to contribute to this wiki - and we'd love to improve it - please shoot us an email requesting an account. Conversely, if we've linked to your material (especially YouTube videos) that you'd prefer that we do not reference, let us know and we will promptly remove those links.<br />
<br />
Categories covered:<br />
<br />
* [[Assembly Language Programming]] <br />
* [[Bit-String Flicking]] <br />
* [[Boolean Algebra]]<br />
* [[Computer Number Systems]]<br />
* [[Data Structures]]<br />
* [[Digital Electronics]] <br />
* [[FSAs and Regular Expressions]] <br />
* [[Graph Theory]]<br />
* [[LISP]] <br />
* [[Prefix/Infix/Postfix Notation]]<br />
* [[Recursive Functions]]<br />
* [[What Does This Program Do?]]<br />
* [//www.acsl.org/categories/C1Elem-ComputerNumberSystems.pdf Elementary Division: Computer Number Systems (Contest 1)]<br />
* [//www.acsl.org/categories/C2Elem-Prefix-Postfix-InfixNotation.pdf Elementary Division: Prefix-Postfix-Infix Notation (Contest 2)]]<br />
* [//www.acsl.org/categories/C3Elem-BooleanAlgebra.pdf Elementary Division: Boolean Algebra (Contest 3)]<br />
* [//www.acsl.org/categories/C4Elem-GraphTheory.pdf Elementary Division: Graph Theory (Contest 4)]<br />
<br />
== Getting started ==<br />
* [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software<br />
* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]<br />
* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Main_Page&diff=608Main Page2018-10-21T08:06:09Z<p>Marc Brown: </p>
<hr />
<div>Welcome to the wiki describing the topics covered in the short programs section of the [//www.acsl.org ACSL] contests.<br />
<br />
If you'd like to contribute to this wiki - and we'd love to improve it - please shoot us an email requesting an account. Conversely, if we've linked to your material (especially YouTube videos) that you'd prefer that we do not reference, let us know and we will promptly remove those links.<br />
<br />
Categories covered:<br />
<br />
* [[Assembly Language Programming]] <br />
* [[Bit-String Flicking]] <br />
* [[Boolean Algebra]]<br />
* [[Computer Number Systems]]<br />
* [[Data Structures]]<br />
* [[Digital Electronics]] <br />
* [[FSAs and Regular Expressions]] <br />
* [[Graph Theory]]<br />
* [[LISP]] <br />
* [[Prefix/Infix/Postfix Notation]]<br />
* [[Recursive Functions]]<br />
* [[What Does This Program Do?]]<br />
* [http://www.acsl.org/categories/C1Elem-ComputerNumberSystems.pdf Elementary Division: Computer Number Systems (Contest 1)]<br />
* [http://www.acsl.org/categories/C2Elem-Prefix-Postfix-InfixNotation.pdf Elementary Division: Prefix-Postfix-Infix Notation (Contest 2)]]<br />
* [http://www.acsl.org/categories/C3Elem-BooleanAlgebra.pdf Elementary Division: Boolean Algebra (Contest 3)]<br />
* [http://www.acsl.org/categories/C4Elem-GraphTheory.pdf Elementary Division: Graph Theory (Contest 4)]<br />
<br />
== Getting started ==<br />
* [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software<br />
* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]<br />
* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=607FSAs and Regular Expressions2018-10-10T02:02:28Z<p>Marc Brown: /* RegEx in Practice */</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising all 4 of the following: 1) a finite number of ''states'', of which exactly one is ''active'' at any given time; 2) ''transition rules'' to change the active state; 3) an ''initial state''; and 4) one or more ''final states''. We can draw an FSA by representing each state as a circle, the final state as a double circle, the start state as the only state with an incoming arrow, and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. "ab" (a followed by b).<br />
::b. UNION. "aUb" or "a|b" (a or b). <br />
::c. CLOSURE. "a*" (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
Similar to standard Algebra, parentheses can be used to group sub-expressions. <br />
For example, "dca*b" generates strings dcb, dcab, dcaab, and so on, whereas<br />
"d(ca)*b" generates strings db, dcab, dcacab, dcacacab, and so on.<br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A "most simplified" Regular Expression or FSA is not always well defined.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= RegEx in Practice =<br />
<br />
Programmers use Regular Expressions (usually referred to as '''regex''') extensively for<br />
expressing patterns to search for. All modern programming languages have regular expression libraries.<br />
<br />
Unfortunately, the specific syntax rules vary depending on the specific <br />
implementation, programming language, or library in use. <br />
Interactive websites for testing regexes are a useful resource for <br />
learning regexes by experimentation. <br />
An excellent online tool is [https://regex101.com/ https://regex101.com/]. <br />
<br />
Here are the additional syntax rules that we will use. They are pretty universal across all<br />
regex packages. <br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
! <nowiki>|</nowiki><br />
|As described above, a vertical bar separates alternatives. For example, gray<nowiki>|</nowiki>grey can match "gray" or "grey".<br />
|-<br />
!*<br />
|As described above, the asterisk indicates zero or more occurrences of the preceding element. For example, ab*c matches "ac", "abc", "abbc", "abbbc", and so on.<br />
|-<br />
!?<br />
| The question mark indicates zero or one occurrences of the preceding element. For example, colou?r matches both "color" and "colour".<br />
|-<br />
! +<br />
| The plus sign indicates one or more occurrences of the preceding element. For example, ab+c matches "abc", "abbc", "abbbc", and so on, but not "ac".<br />
|-<br />
! .<br />
| The wildcard . matches any character. For example, a.b matches any string that contains an "a", then any other character, and then a "b" such as "a7b", "a&b", or "arb", but not "abbb". Therefore, a.*b matches any string that contains an "a" and a "b" with 0 or more characters in between. This includes "ab", "acb", or "a123456789b".<br />
|-<br />
! [ ]<br />
| A bracket expression matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", or "z", as does [a-cx-z].<br />
|-<br />
! [^ ]<br />
|Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". Likewise, literal characters and ranges can be mixed.<br />
|-<br />
!( )<br />
| <br />
As described above, parentheses define a sub-expression. For example, the pattern H(ä|ae?)ndel matches "Handel", "Händel", and "Haendel".<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 matches strings starting with one or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 matches strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s followed by some 0s. Choice A and E following this pattern.<br />
<br />
<!--<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (a U b)(ab*)(b* U a)<br />
::B. (aab* U bab*)a<br />
::C. aab* U bab* U aaba U bab*a<br />
::D. aab* U bab* U aab*a U bab*a<br />
::E. a* U b* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
--><br />
== Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-D]*[a-d]*[0-9]" ?<br />
<br />
::1. ABCD8<br />
::2. abcd5<br />
::3. ABcd9<br />
::4. AbCd7<br />
::5. X<br />
::6. abCD7<br />
::7. DCCBBBaaaa5<br />
<br />
'''Solution:'''<br />
<br />
The pattern describes strings the start with zero or more uppercase letters A, B, C, or D (in any order), followed<br />
by zero or more lowercase letter a, b, c, or d (in any order), followed by a single digit.<br />
The strings that are represented by this pattern are 1, 2, 3, and 7.<br />
<br />
== Problem 4 ==<br />
<br />
Which of the following strings match the regular expression pattern "Hi?g+h+[^a-ceiou]" ?<br />
<br />
::1. Highb<br />
::2. HiiighS<br />
::3. HigghhhC<br />
::4. Hih<br />
::5. Hghe<br />
::6. Highd<br />
::7. HgggggghX<br />
<br />
'''Solution:'''<br />
<br />
The ? indicates 0 or 1 "i"s. The + indicates 1 or more "g"s followed by 1 or more "h"s. <br />
The ^ indicates that the last character cannot be lower-case a, b, c, e, i, o, or u.<br />
The strings that are represented by this pattern are 3, 6, and 7. <br />
<br />
<!--<br />
== Problem 5 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-E|a-e]*(00[01])|([10]11)" ?<br />
<br />
::1. DAD001<br />
::2. bad000<br />
::3. aCe0011<br />
::4. AbE111<br />
::5. AAAbbC<br />
::6. aBBBe011<br />
::7. 001011<br />
<br />
'''Solution:'''<br />
<br />
The [A-E|a-e]* allows for any of those letters in any order 0 or more times. Therefore, all of the <br />
choices match at the beginning of the string. The end of the string must match "000", "001", "111", <br />
or "011". That means that 1, 2, 4, and 6 match.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=606FSAs and Regular Expressions2018-10-10T01:45:39Z<p>Marc Brown: /* RegEx in Practice */</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising all 4 of the following: 1) a finite number of ''states'', of which exactly one is ''active'' at any given time; 2) ''transition rules'' to change the active state; 3) an ''initial state''; and 4) one or more ''final states''. We can draw an FSA by representing each state as a circle, the final state as a double circle, the start state as the only state with an incoming arrow, and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. "ab" (a followed by b).<br />
::b. UNION. "aUb" or "a|b" (a or b). <br />
::c. CLOSURE. "a*" (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
Similar to standard Algebra, parentheses can be used to group sub-expressions. <br />
For example, "dca*b" generates strings dcb, dcab, dcaab, and so on, whereas<br />
"d(ca)*b" generates strings db, dcab, dcacab, dcacacab, and so on.<br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A "most simplified" Regular Expression or FSA is not always well defined.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= RegEx in Practice =<br />
<br />
Programmers use Regular Expressions (usually referred to as '''regex''') extensively for<br />
expressing patterns to search for. All modern programming languages have regular expression libraries.<br />
<br />
Unfortunately, the specific syntax rules vary depending on the specific <br />
implementation, programming language, or library in use. <br />
Interactive websites for testing regexes are a useful resource for <br />
learning regexes by experimentation. <br />
An excellent online tool is [https://regex101.com/ https://regex101.com/]. <br />
<br />
Here are the additional syntax rules that we will use. They are pretty universal across all<br />
regex packages. <br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
! <nowiki>|</nowiki><br />
|As described above, a vertical bar separates alternatives. For example, gray<nowiki>|</nowiki>grey can match "gray" or "grey".<br />
|-<br />
!*<br />
|As described above, the asterisk indicates zero or more occurrences of the preceding element. For example, ab*c matches "ac", "abc", "abbc", "abbbc", and so on.<br />
|-<br />
!?<br />
| The question mark indicates zero or one occurrences of the preceding element. For example, colou?r matches both "color" and "colour".<br />
|-<br />
! +<br />
| The plus sign indicates one or more occurrences of the preceding element. For example, ab+c matches "abc", "abbc", "abbbc", and so on, but not "ac".<br />
|-<br />
! .<br />
| The wildcard . matches any character. For example, a.b matches any string that contains an "a", then any other character, and then a "b" such as "a7b", "a&b", or "arb", but not "abbb". Therefore, a.*b matches any string that contains an "a" and a "b" with 0 or more characters in between. This includes "ab", "acb", or "a123456789b".<br />
|-<br />
! [ ]<br />
| A bracket expression matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", or "z", as does [a-cx-z].<br />
|-<br />
! [^ ]<br />
|Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". Likewise, literal characters and ranges can be mixed.<br />
|-<br />
!( )<br />
| As described above, parentheses define a sub-expression. For example, the pattern H(ä|ae?)ndel matches "Handel", "Händel", and "Haendel".<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 matches strings starting with one or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 matches strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s followed by some 0s. Choice A and E following this pattern.<br />
<br />
<!--<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (a U b)(ab*)(b* U a)<br />
::B. (aab* U bab*)a<br />
::C. aab* U bab* U aaba U bab*a<br />
::D. aab* U bab* U aab*a U bab*a<br />
::E. a* U b* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
--><br />
== Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-D]*[a-d]*[0-9]" ?<br />
<br />
::1. ABCD8<br />
::2. abcd5<br />
::3. ABcd9<br />
::4. AbCd7<br />
::5. X<br />
::6. abCD7<br />
::7. DCCBBBaaaa5<br />
<br />
'''Solution:'''<br />
<br />
The pattern describes strings the start with zero or more uppercase letters A, B, C, or D (in any order), followed<br />
by zero or more lowercase letter a, b, c, or d (in any order), followed by a single digit.<br />
The strings that are represented by this pattern are 1, 2, 3, and 7.<br />
<br />
== Problem 4 ==<br />
<br />
Which of the following strings match the regular expression pattern "Hi?g+h+[^a-ceiou]" ?<br />
<br />
::1. Highb<br />
::2. HiiighS<br />
::3. HigghhhC<br />
::4. Hih<br />
::5. Hghe<br />
::6. Highd<br />
::7. HgggggghX<br />
<br />
'''Solution:'''<br />
<br />
The ? indicates 0 or 1 "i"s. The + indicates 1 or more "g"s followed by 1 or more "h"s. <br />
The ^ indicates that the last character cannot be lower-case a, b, c, e, i, o, or u.<br />
The strings that are represented by this pattern are 3, 6, and 7. <br />
<br />
<!--<br />
== Problem 5 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-E|a-e]*(00[01])|([10]11)" ?<br />
<br />
::1. DAD001<br />
::2. bad000<br />
::3. aCe0011<br />
::4. AbE111<br />
::5. AAAbbC<br />
::6. aBBBe011<br />
::7. 001011<br />
<br />
'''Solution:'''<br />
<br />
The [A-E|a-e]* allows for any of those letters in any order 0 or more times. Therefore, all of the <br />
choices match at the beginning of the string. The end of the string must match "000", "001", "111", <br />
or "011". That means that 1, 2, 4, and 6 match.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=603FSAs and Regular Expressions2018-10-09T19:32:41Z<p>Marc Brown: /* Sample Problems */</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising all 4 of the following: 1) a finite number of ''states'', of which exactly one is ''active'' at any given time; 2) ''transition rules'' to change the active state; 3) an ''initial state''; and 4) one or more ''final states''. We can draw an FSA by representing each state as a circle, the final state as a double circle, the start state as the only state with an incoming arrow, and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. "ab" (a followed by b).<br />
::b. UNION. "aUb" or "a|b" (a or b). <br />
::c. CLOSURE. "a*" (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
Similar to standard Algebra, parentheses can be used to group sub-expressions. <br />
For example, "dca*b" generates strings dcb, dcab, dcaab, and so on, whereas<br />
"d(ca)*b" generates strings db, dcab, dcacab, dcacacab, and so on.<br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A "most simplified" Regular Expression or FSA is not always well defined.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= RegEx in Practice =<br />
<br />
Programmers use Regular Expressions (usually referred to as '''regex''') extensively for<br />
expressing patterns to search for. All modern programming languages have regular expression libraries.<br />
<br />
Unfortunately, the specific syntax rules vary depending on the specific <br />
implementation, programming language, or library in use. <br />
Interactive websites for testing regexes are a useful resource for <br />
learning regexes by experimentation. <br />
An excellent online tool is [https://regex101.com/ https://regex101.com/]. <br />
<br />
Here are the additional syntax rules that we will use. They are pretty universal across all<br />
regex packages. <br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
! <nowiki>|</nowiki><br />
|As described above, a vertical bar separates alternatives. For example, gray<nowiki>|</nowiki>grey can match "gray" or "grey".<br />
|-<br />
!*<br />
|As described above, the asterisk indicates zero or more occurrences of the preceding element. For example, ab*c matches "ac", "abc", "abbc", "abbbc", and so on.<br />
|-<br />
!?<br />
| The question mark indicates zero or one occurrences of the preceding element. For example, colou?r matches both "color" and "colour".<br />
|-<br />
! +<br />
| The plus sign indicates one or more occurrences of the preceding element. For example, ab+c matches "abc", "abbc", "abbbc", and so on, but not "ac".<br />
|-<br />
! .<br />
| The wildcard . matches any character. For example, a.b matches any string that contains an "a", then any other character, and then a "b" such as "a7b", "a&b", or "arb", but not "abbb". Therefore, a.*b matches any string that contains an "a" and a "b" with 0 or more characters in between. This includes "ab", "acb", or "a123456789b".<br />
|-<br />
! [ ]<br />
| A bracket expression matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", or "z", as does [a-cx-z].<br />
|-<br />
! [^ ]<br />
|Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". Likewise, literal characters and ranges can be mixed.<br />
|-<br />
!( )<br />
| As described above, parentheses define a sub-expression. For example, <br />
the pattern H(ä|ae?)ndel matches "Handel", "Händel", and "Haendel".<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 matches strings starting with one or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 matches strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s followed by some 0s. Choice A and E following this pattern.<br />
<br />
<!--<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (a U b)(ab*)(b* U a)<br />
::B. (aab* U bab*)a<br />
::C. aab* U bab* U aaba U bab*a<br />
::D. aab* U bab* U aab*a U bab*a<br />
::E. a* U b* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
--><br />
== Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-D]*[a-d]*[0-9]" ?<br />
<br />
::1. ABCD8<br />
::2. abcd5<br />
::3. ABcd9<br />
::4. AbCd7<br />
::5. X<br />
::6. abCD7<br />
::7. DCCBBBaaaa5<br />
<br />
'''Solution:'''<br />
<br />
The pattern describes strings the start with zero or more uppercase letters A, B, C, or D (in any order), followed<br />
by zero or more lowercase letter a, b, c, or d (in any order), followed by a single digit.<br />
The strings that are represented by this pattern are 1, 2, 3, and 7.<br />
<br />
== Problem 4 ==<br />
<br />
Which of the following strings match the regular expression pattern "Hi?g+h+[^a-ceiou]" ?<br />
<br />
::1. Highb<br />
::2. HiiighS<br />
::3. HigghhhC<br />
::4. Hih<br />
::5. Hghe<br />
::6. Highd<br />
::7. HgggggghX<br />
<br />
'''Solution:'''<br />
<br />
The ? indicates 0 or 1 "i"s. The + indicates 1 or more "g"s followed by 1 or more "h"s. <br />
The ^ indicates that the last character cannot be lower-case a, b, c, e, i, o, or u.<br />
The strings that are represented by this pattern are 3, 6, and 7. <br />
<!--<br />
== Problem 5 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-E|a-e]*00[0?|1+]11" ?<br />
<br />
::1. DAD0011111111<br />
::2. bad0000000111<br />
::3. aCe0010101011<br />
::4. AbE000111<br />
::5. AAAbbC0011<br />
::6. aBBBe01<br />
::7. 000000111111<br />
<br />
'''Solution:'''<br />
<br />
The [A-E|a-e]* allows for any of those letters in any order 0 or more times. Therefore, all of the<br />
choices match at the beginning of the string. The end of the string must start with 00 and end with 11. <br />
In between, there must be 0 or 1 "0"s or 1 or more "1"s. That means that 1, 2, 4, and 7 match.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=601FSAs and Regular Expressions2018-10-07T22:48:06Z<p>Marc Brown: /* Problem 6 */</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising all 4 of the following: 1) a finite number of ''states'', of which exactly one is ''active'' at any given time; 2) ''transition rules'' to change the active state; 3) an ''initial state''; and 4) one or more ''final states''. We can draw an FSA by representing each state as a circle, the final state as a double circle, the start state as the only state with an incoming arrow, and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. "ab" (a followed by b).<br />
::b. UNION. "aUb" or "a|b" (a or b). <br />
::c. CLOSURE. "a*" (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
Similar to standard Algebra, parentheses can be used to group sub-expressions. <br />
For example, "dca*b" generates strings dcb, dcab, dcaab, and so on, whereas<br />
"d(ca)*b" generates strings db, dcab, dcacab, dcacacab, and so on.<br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A "most simplified" Regular Expression or FSA is not always well defined.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= RegEx in Practice =<br />
<br />
Programmers use Regular Expressions (usually referred to as '''regex''') extensively for<br />
expressing patterns to search for. All modern programming languages have regular expression libraries.<br />
<br />
Unfortunately, the specific syntax rules vary depending on the specific <br />
implementation, programming language, or library in use. <br />
Interactive websites for testing regexes are a useful resource for <br />
learning regexes by experimentation. <br />
An excellent online tool is [https://regex101.com/ https://regex101.com/]. <br />
<br />
Here are the additional syntax rules that we will use. They are pretty universal across all<br />
regex packages. <br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
! <nowiki>|</nowiki><br />
|As described above, a vertical bar separates alternatives. For example, gray<nowiki>|</nowiki>grey can match "gray" or "grey".<br />
|-<br />
!*<br />
|As described above, the asterisk indicates zero or more occurrences of the preceding element. For example, ab*c matches "ac", "abc", "abbc", "abbbc", and so on.<br />
|-<br />
!?<br />
| The question mark indicates zero or one occurrences of the preceding element. For example, colou?r matches both "color" and "colour".<br />
|-<br />
! +<br />
| The plus sign indicates one or more occurrences of the preceding element. For example, ab+c matches "abc", "abbc", "abbbc", and so on, but not "ac".<br />
|-<br />
! .<br />
| The wildcard . matches any character. For example, a.b matches any string that contains an "a", then any other character, and then a "b" such as "a7b", "a&b", or "arb", but not "abbb". Therefore, a.*b matches any string that contains an "a" and a "b" with 0 or more characters in between. This includes "ab", "acb", or "a123456789b".<br />
|-<br />
! [ ]<br />
| A bracket expression matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", or "z", as does [a-cx-z].<br />
|-<br />
! [^ ]<br />
|Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". Likewise, literal characters and ranges can be mixed.<br />
|-<br />
!( )<br />
| As described above, parentheses define a sub-expression. For example, <br />
the pattern H(ä|ae?)ndel matches "Handel", "Händel", and "Haendel".<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 matches strings starting with one or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 matches strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s followed by some 0s. Choice A and E following this pattern.<br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (a U b)(ab*)(b* U a)<br />
::B. (aab* U bab*)a<br />
::C. aab* U bab* U aaba U bab*a<br />
::D. aab* U bab* U aab*a U bab*a<br />
::E. a* U b* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
== Problem 4 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-D]*[a-d]*[0-9]" ?<br />
<br />
::1. ABCD8<br />
::2. abcd5<br />
::3. ABcd9<br />
::4. AbCd7<br />
::5. X<br />
::6. abCD7<br />
::7. DCCBBBaaaa5<br />
<br />
'''Solution:'''<br />
<br />
The pattern describes strings the start with zero or more uppercase letters A, B, C, or D (in any order), followed<br />
by zero or more lowercase letter a, b, c, or d (in any order), followed by a single digit.<br />
The strings that are represented by this pattern are 1, 2, 3, and 7.<br />
<br />
== Problem 5 ==<br />
<br />
Which of the following strings match the regular expression pattern "Hi?g+h+[^a-ceiou]" ?<br />
<br />
::1. Highb<br />
::2. HiiighS<br />
::3. HigghhhC<br />
::4. Hih<br />
::5. Hghe<br />
::6. Highd<br />
::7. HgggggghX<br />
<br />
'''Solution:'''<br />
<br />
The ? indicates 0 or 1 "i"s. The + indicates 1 or more "g"s followed by 1 or more "h"s. <br />
The ^ indicates that the last character cannot be lower-case a, b, c, e, i, o, or u.<br />
The strings that are represented by this pattern are 3, 6, and 7. <br />
<br />
<!--<br />
== Problem 6 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-E|a-e]*01[0?|1+]10" ?<br />
<br />
::1. DAD0111111110<br />
::2. bad01110<br />
::3. aCe01000110<br />
::4. AbE0101110<br />
::5. AAAbbC01000001<br />
::6. aBBBe010110<br />
::7. 011111110<br />
<br />
'''Solution:'''<br />
<br />
The [A-E|a-e]* allows for any of those letters in any order 0 or more times. Therefore, all of the<br />
choices match at the beginning of the string. The end of the string must start with 01 and end with 10. <br />
In between, there must be 0 or 1 "0"s or 1 or more "1"s. That means that 1, 2, 4, 6, and 7 match.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=599FSAs and Regular Expressions2018-10-04T01:22:19Z<p>Marc Brown: /* RegEx in Practice */</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one or more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. "ab" (a followed by b).<br />
::b. UNION. "aUb" or "a|b" (a or b). <br />
::c. CLOSURE. "a*" (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
Similar to standard Algebra, parentheses can be used to group subexpressions. <br />
For example, "dca*b" generates strings dcb, dcab, dcaab, and so on, whereas<br />
"d(ca)*b" generates string db, dcab, dcacab, dcacacab, and so on.<br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A "most simplified" Regular Expression or FSA is not always well defined. <br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= RegEx in Practice =<br />
<br />
Programmers use Regular Expressions (usually referred to as '''regex''') extensively for<br />
expressing patterns to search for. All modern programming languages have <br />
regular expression libraries. <br />
<br />
Unfortunately, the specific syntax rules vary depending on the specific <br />
implementation, programming language, or library in use. <br />
Interactive websites for testing regexes are a useful resource for <br />
learning regexes by experimentation. <br />
An excellent online tool is [https://regex101.com/ https://regex101.com/]. <br />
<br />
Here are the additional syntax that we will use; it's pretty universal across all<br />
regex packages. <br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
! <nowiki>|</nowiki><br />
|As described above, a vertical bar separates alternatives. For example, gray<nowiki>|</nowiki>grey can match "gray" or "grey".<br />
|-<br />
!*<br />
|As described above, the asterisk indicates zero or more occurrences of the preceding element. For example, ab*c matches "ac", "abc", "abbc", "abbbc", and so on.<br />
|-<br />
!?<br />
| The question mark indicates zero or one occurrences of the preceding element. For example, colou?r matches both "color" and "colour".<br />
|-<br />
! +<br />
| The plus sign indicates one or more occurrences of the preceding element. For example, ab+c matches "abc", "abbc", "abbbc", and so on, but not "ac".<br />
|-<br />
! .<br />
| The wildcard . matches any character. For example, a.b matches any string that contains an "a", then any other character and then a "b", a.*b matches any string that contains an "a" and a "b" at some later point.<br />
|-<br />
! [ ]<br />
| A bracket expression. Matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", or "z", as does [a-cx-z].<br />
|-<br />
! [^ ]<br />
|Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". Likewise, literal characters and ranges can be mixed.<br />
|-<br />
!( )<br />
| As described above, parentheses define a subexpression. For example, <br />
the pattern H(ä|ae?)ndel matches "Handel", "Händel", and "Haendel".<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 are strings starting with one or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 are strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s followed by some 0s. Choice A and E following this pattern.<br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (a U b)(ab*)(b* U a)<br />
::B. (aab* U bab*)a<br />
::C. aab* U bab* U aaba U bab*a<br />
::D. aab* U bab* U aab*a U bab*a<br />
::E. a* U b* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
== Problem 4 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-D]*[a-d]*[0-9]" ?<br />
<br />
::1. ABCD8<br />
::2. abcd5<br />
::3. ABcd9<br />
::4. AbCd7<br />
::5. X<br />
::6. abCD7<br />
::7. DCCBBBaaaa5<br />
<br />
'''Solution:'''<br />
<br />
The pattern describes strings the start with zero or more uppercase letters A, B, C, or D (in any order), followed<br />
by zero or more lowercase letter a, b, c, or d (in any order), followed by a single digit.<br />
The strings that are not represented by the patter are 4, 5, and 6.<br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=598FSAs and Regular Expressions2018-10-04T01:11:31Z<p>Marc Brown: </p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one or more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. "ab" (a followed by b).<br />
::b. UNION. "aUb" or "a|b" (a or b). <br />
::c. CLOSURE. "a*" (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
Similar to standard Algebra, parentheses can be used to group subexpressions. <br />
For example, "dca*b" generates strings dcb, dcab, dcaab, and so on, whereas<br />
"d(ca)*b" generates string db, dcab, dcacab, dcacacab, and so on.<br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A "most simplified" Regular Expression or FSA is not always well defined. <br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= RegEx in Practice =<br />
<br />
Programmers use Regular Expressions (usually referred to as '''regex''') extensively for<br />
expressing patterns to search for. All modern programming languages have <br />
regular expression libraries. <br />
<br />
Unfortunately, the specific syntax rules vary depending on the specific <br />
implementation, programming language, or library in use. <br />
Interactive websites for testing regexes are a useful resource for <br />
learning regexes by experimentation. <br />
An excellent online too isl [https://regex101.com/ https://regex101.com/]. <br />
<br />
Here are the additional syntax that we will use; it's pretty universal across all<br />
regex packages. <br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
! <nowiki>|</nowiki><br />
|As described above, a vertical bar separates alternatives. For example, gray<nowiki>|</nowiki>grey can match "gray" or "grey".<br />
|-<br />
!*<br />
|As described above, the asterisk indicates zero or more occurrences of the preceding element. For example, ab*c matches "ac", "abc", "abbc", "abbbc", and so on.<br />
|-<br />
!?<br />
| The question mark indicates zero or one occurrences of the preceding element. For example, colou?r matches both "color" and "colour".<br />
|-<br />
! +<br />
| The plus sign indicates one or more occurrences of the preceding element. For example, ab+c matches "abc", "abbc", "abbbc", and so on, but not "ac".<br />
|-<br />
! .<br />
| The wildcard . matches any character. For example, a.b matches any string that contains an "a", then any other character and then a "b", a.*b matches any string that contains an "a" and a "b" at some later point.<br />
|-<br />
! [ ]<br />
| A bracket expression. Matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", or "z", as does [a-cx-z].<br />
|-<br />
! [^ ]<br />
|Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". Likewise, literal characters and ranges can be mixed.<br />
|-<br />
!( )<br />
| As described above, parentheses define a subexpression. For example, <br />
the pattern H(ä|ae?)ndel matches "Handel", "Händel", and "Haendel".<br />
|}<br />
<br />
<br />
= Sample Problems =<br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 are strings starting with one or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 are strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s followed by some 0s. Choice A and E following this pattern.<br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (a U b)(ab*)(b* U a)<br />
::B. (aab* U bab*)a<br />
::C. aab* U bab* U aaba U bab*a<br />
::D. aab* U bab* U aab*a U bab*a<br />
::E. a* U b* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
== Problem 4 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-D]*[a-d]*[0-9]" ?<br />
<br />
::1. ABCD8<br />
::2. abcd5<br />
::3. ABcd9<br />
::4. AbCd7<br />
::5. X<br />
::6. abCD7<br />
::7. DCCBBBaaaa5<br />
<br />
'''Solution:'''<br />
<br />
The pattern describes strings the start with zero or more uppercase letters A, B, C, or D (in any order), followed<br />
by zero or more lowercase letter a, b, c, or d (in any order), followed by a single digit.<br />
The strings that are not represented by the patter are 4, 5, and 6.<br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=597FSAs and Regular Expressions2018-10-04T01:07:40Z<p>Marc Brown: </p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one or more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. "ab" (a followed by b).<br />
::b. UNION. "aUb" or "a|b" (a or b). <br />
::c. CLOSURE. "a*" (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
Similar to standard Algebra, parentheses can be used to group subexpressions. <br />
For example, "dca*b" generates strings dcb, dcab, dcaab, and so on, whereas<br />
"d(ca)*b" generates string db, dcab, dcacab, dcacacab, and so on.<br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A "most simplified" Regular Expression or FSA is not always well defined. <br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Regular Expression in Practice =<br />
<br />
Programmers use Regular Expressions (usually referred to as '''regex''') extensively for<br />
expressing patterns to search for. All modern programming languages have <br />
regular expression libraries. <br />
<br />
Unfortunately, the specific syntax rules vary depending on the specific <br />
implementation, programming language, or library in use. <br />
Interactive websites for testing regexes are a useful resource for <br />
learning regexes by experimentation. <br />
An excellent online tool [https://regex101.com/ https://regex101.com/]<br />
for the Python language.<br />
<br />
Here are the additional syntax that we will use; it's pretty universal across all<br />
regex packages. <br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
! <nowiki>|</nowiki><br />
|As described above, a vertical bar separates alternatives. For example, gray<nowiki>|</nowiki>grey can match "gray" or "grey".<br />
|-<br />
!*<br />
|As described above, the asterisk indicates zero or more occurrences of the preceding element. For example, ab*c matches "ac", "abc", "abbc", "abbbc", and so on.<br />
|-<br />
!?<br />
| The question mark indicates zero or one occurrences of the preceding element. For example, colou?r matches both "color" and "colour".<br />
|-<br />
! +<br />
| The plus sign indicates one or more occurrences of the preceding element. For example, ab+c matches "abc", "abbc", "abbbc", and so on, but not "ac".<br />
|-<br />
! .<br />
| The wildcard . matches any character. For example, a.b matches any string that contains an "a", then any other character and then a "b", a.*b matches any string that contains an "a" and a "b" at some later point.<br />
|-<br />
! [ ]<br />
| A bracket expression. Matches a single character that is contained within the brackets. For example, [abc] matches "a", "b", or "c". [a-z] specifies a range which matches any lowercase letter from "a" to "z". These forms can be mixed: [abcx-z] matches "a", "b", "c", "x", "y", or "z", as does [a-cx-z].<br />
|-<br />
! [^ ]<br />
|Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than "a", "b", or "c". [^a-z] matches any single character that is not a lowercase letter from "a" to "z". Likewise, literal characters and ranges can be mixed.<br />
|-<br />
!( )<br />
| As described above, parentheses define a subexpression. For example, <br />
the pattern H(ä|ae?)ndel matches "Handel", "Händel", and "Haendel".<br />
|}<br />
<br />
<br />
= Sample Problems =<br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 are strings starting with one or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 are strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s followed by some 0s. Choice A and E following this pattern.<br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (a U b)(ab*)(b* U a)<br />
::B. (aab* U bab*)a<br />
::C. aab* U bab* U aaba U bab*a<br />
::D. aab* U bab* U aab*a U bab*a<br />
::E. a* U b* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
== Problem 4 ==<br />
<br />
Which of the following strings match the regular expression pattern "[A-D]*[a-d]*[0-9]" ?<br />
<br />
::1. ABCD8<br />
::2. abcd5<br />
::3. ABcd9<br />
::4. AbCd7<br />
::5. X<br />
::6. abCD7<br />
::7. DCCBBBaaaa5<br />
<br />
'''Solution:'''<br />
<br />
The pattern describes strings the start with zero or more uppercase letters A, B, C, or D (in any order), followed<br />
by zero or more lowercase letter a, b, c, or d (in any order), followed by a single digit.<br />
The strings that are not represented by the patter are 4, 5, and 6.<br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=596FSAs and Regular Expressions2018-10-03T23:43:32Z<p>Marc Brown: /* Basics */</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one or more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. ''ab'' (a followed by b).<br />
::b. UNION. ''aUb'' or ''a|b'' (a or b). <br />
::c. CLOSURE. ''a*'' (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
Identities for Regular Expressions appear in the next section. The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
<br />
Similar to standard Algebra, parentheses can be used to group subexpressions. For example, ''(ab)*'' generates the strings λ, ab, abab, ababab, and so on; whereas ''ab*'' generates strings a, ab, abb, abbb, and so on. <br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A “most simplified” Regular Expression or FSA is not always well defined. <br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 are strings starting with one or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 are strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s followed by some 0s. Choice A and E following this pattern.<br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (a U b)(ab*)(b* U a)<br />
::B. (aab* U bab*)a<br />
::C. aab* U bab* U aaba U bab*a<br />
::D. aab* U bab* U aab*a U bab*a<br />
::E. a* U b* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
<!--<br />
== Problem 4 ==<br />
<br />
Which of the following strings match the regular expression pattern "?[A-D]*[a-d]*#" ?<br />
<br />
::A. 8AAAabd4<br />
::B. MM5<br />
::C. AAAAAAAA7<br />
::D. Abcd9<br />
::E. &dd88<br />
::F. >BAD0<br />
<br />
'''Solution:'''<br />
<br />
The answer is A, C, D, and F. In B, the character M is not in the range A-D or a-d. In E, there cannot be more than 1 digit at the end of the string. Remember that an asterisk represents 0 or more of that character or range of characters.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Assembly_Language_Programming&diff=594Assembly Language Programming2018-09-14T18:48:15Z<p>Marc Brown: /* Reference Manual */</p>
<hr />
<div>Programs written in high-level languages are traditionally converted by compilers into assembly language, which is turned into machine language programs – sequences of 1’s and 0’s – by an assembler. Even today, with very good quality compilers available, there is the need for programmers to understand assembly language. First, it provides programmers with a better understanding of the compiler and its constraints. Second, on occasion, programmers find themselves needing to program directly in assembly language in order to meet constraints in execution speed or space. <br />
<br />
ACSL chose to define its own assembly language rather than use a “real” one in order to eliminate the many sticky details associated with real languages. The basic concepts of our ACSL topic description are common to all assembly languages. <br />
<br />
== Reference Manual ==<br />
<br />
Execution starts at the first line of the program and continues sequentially, except for branch instructions (BG, BE, BL, BU), until the end instruction (END) is encountered. The result of each operation is stored in a special word of memory, called the “accumulator” (ACC). Each line of an assembly language program has the following fields (lower-case indicates optional components):<br />
<br />
label OPCODE LOC comments<br />
<br />
The ''label'' is a character string beginning in the first column. Valid OPCODE’s are listed in the chart below. The LOC field is either a reference to a label or ''immediate data''. For example, “LOAD A” would put the contents referenced by the label “A” into the ACC; “LOAD =123” would store the value 123 in the ACC. Only those instructions that do not modify the LOC field can use the “immediate data” format. In the following chart, they are indicated by an asterisk in the first column.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!OP CODE<br />
!DESCRIPTION<br />
<br />
|-<br />
!*LOAD<br />
|The contents of LOC are placed in the ACC. LOC is unchanged.<br />
<br />
|-<br />
!STORE<br />
|The contents of the ACC are placed in the LOC. ACC is unchanged.<br />
<br />
|-<br />
!*ADD<br />
|The contents of LOC are added to the contents of the ACC. The sum is stored in the ACC. LOC is unchanged. Addition is modulo 1,000,000.<br />
<br />
|-<br />
!*SUB<br />
|The contents of LOC are subtracted from the contents of the ACC. The difference is stored in the ACC. LOC is unchanged. Subtraction is modulo 1,000,000.<br />
<br />
|-<br />
!*MULT<br />
|The contents of LOC are multiplied by the contents of the ACC. The product is stored in the ACC. LOC is unchanged. Multiplication is modulo 1,000,000.<br />
<br />
|-<br />
!*DIV<br />
|The contents of LOC are divided into the contents of the ACC. The signed integer part of the quotient is stored in the ACC. LOC is unchanged.<br />
.<br />
|-<br />
!BG<br />
|<br />
Branch to the instruction labeled with LOC if ACC>0.<br />
<br />
|-<br />
!BE<br />
|<br />
Branch to the instruction labeled with LOC if ACC=0.<br />
<br />
|-<br />
!BL<br />
|<br />
Branch to the instruction labeled with LOC if ACC<0.<br />
<br />
|-<br />
!BU<br />
|Branch to the instruction labeled with LOC.<br />
<br />
|-<br />
!READ<br />
|<br />
Read a signed integer (modulo 1,000,000) into LOC.<br />
<br />
|-<br />
!PRINT<br />
|<br />
Print the contents of LOC.<br />
<br />
|-<br />
!DC<br />
|<br />
The value of the memory word defined by the LABEL field is defined to contain the specified constant. The LABEL field is mandatory for this opcode. The ACC is not modified.<br />
<br />
|-<br />
!END<br />
| <br />
Program terminates. LOC field is ignored.<br />
|}<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
After the following program is executed, <br />
what value is in location TEMP?<br />
<br />
{|class="wikitable" style="text-align: left"<br />
|TEMP || DC || 0<br />
|-<br />
|A||DC||8<br />
|-<br />
|B||DC||-2<br />
|-<br />
|C||DC||3<br />
|-<br />
| ||LOAD||B<br />
|-<br />
| ||MULT||C<br />
|-<br />
| ||ADD||A<br />
|-<br />
| ||DIV||B<br />
|-<br />
| ||SUB||A<br />
|-<br />
| ||STORE||TEMP<br />
|-<br />
| ||END||<br />
|}<br />
<br />
'''Solution:''' The ACC takes on values -2, -6, 2, -1, and -9 in that order. The last value, -9, is stored in location TEMP.<br />
<br />
=== Problem 2 ===<br />
<br />
If the following program has an input value<br />
of N, what is the final value of X which is<br />
computed? Express X as an algebraic<br />
expression in terms of N. <br />
<br />
{|class="wikitable" style="text-align: left"<br />
| || READ || X<br />
|-<br />
| || LOAD || X<br />
|-<br />
|TOP || SUB || =1<br />
|-<br />
| || BE || DONE<br />
|-<br />
| || STORE || A<br />
|-<br />
| || MULT || X<br />
|-<br />
| || STORE || X<br />
|-<br />
| || LOAD || A<br />
|-<br />
| || BU || TOP<br />
|-<br />
|DONE || END || <br />
|}<br />
<br />
'''Solution:''' This program loops between labels TOP and<br />
DONE for A times. A has an initial value of X and subsequent terms of N,<br />
then values of A-1, A-2, …, 1. Each time through the loop,<br />
X is multiplied by the the current value of A.<br />
Thus, X = A * (A-1) * (A-2) * … * 1 or X=A! or A factorial.<br />
For example, 5! = 5 * 4 * 3 * 2 * 1 = 120. Since the<br />
initial value of A is the number input (i.e. N),<br />
the algebraic expression is X = N!.<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/RUm3iHsbO3I</youtube><br />
| [https://youtu.be/RUm3iHsbO3I ''Intro to Assembly Language'' ('''CalculusNguyenify''')]<br />
<br />
A general introduction into assembly language. In particular, it covers how it fits into the source code to an executable image pipeline.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/i_JYT398O64</youtube><br />
| [https://youtu.be/i_JYT398O64 ''Syntax of ACSL Assembly Language'' ('''CalculusNguyenify''')]<br />
<br />
A very nice introduction to this ACSL category.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/NEQASUsZ0g4</youtube><br />
| [https://youtu.be/NEQASUsZ0g4 ''Examples'' ('''CalculusNguyenify''')]<br />
<br />
Walks through a couple of ACSL Assembly language programs that have been used in previous contests.<br />
<br />
|}<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=590FSAs and Regular Expressions2018-09-13T00:08:56Z<p>Marc Brown: /* Video Resources */</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state, so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. “ab” (a followed by b).<br />
::b. UNION. “aUb” (a or b). <br />
::c. CLOSURE. “a*” (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
Identities for Regular Expressions appear in the next section. The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A “most simplified” Regular Expression or FSA is not always well defined. <br />
<!--<br />
Most programming languages today have a package to handle Regular Expressions in order to do pattern matching algorithms more easily. Visual BASIC has the LIKE operator that is very easy to use. We will use these “basic” symbols in our category description.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
|?<br />
|Any single character<br />
|-<br />
|*<br />
|Zero or more of the preceding character<br />
|-<br />
|#<br />
|Any single digit<br />
|-<br />
|[ char-char,char,…]<br />
|Any inclusive range or list of characters<br />
|-<br />
|{![charlist]}<br />
|Any character not in a given range or list<br />
|}<br />
<br />
For example, the following strings either match or don’t match the pattern “[A-M][o-z][!a,e,I,o,u]?#.*”:<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!YES<br />
!NO<br />
!Why not?<br />
|-<br />
|App$5.java<br />
|Help1.<br />
| E is not in the range [o-z].<br />
|-<br />
|Dog&2.py<br />
|IoU$5<br />
|There is no . at the end.<br />
|-<br />
|LzyG3.txt<br />
|move6.py<br />
|The m is not in the range [A-M].<br />
|-<br />
|Hot90.<br />
|MaX7A.txt<br />
|The A is not a digit from 0 to 9.<br />
|}<br />
--><br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 are strings starting with oe or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 are strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s <br />
followed by some 0s. Choice A and E following this pattern.<br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (aUb)(ab*)(b*Ua)<br />
::B. (aab*Ubab*)a<br />
::C. aab*Ubab*UaabaUbab*a<br />
::D. aab*Ubab*Uaab*aUbab*a<br />
::E. a*Ub* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
<!--<br />
== Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "?[A-D]*[a-d]*#" ?<br />
<br />
::A. 8AAAabd4<br />
::B. MM5<br />
::C. AAAAAAAA7<br />
::D. Abcd9<br />
::E. &dd88<br />
::F. >BAD0<br />
<br />
'''Solution:'''<br />
<br />
The answer is A, C, D, and F. In B the character M is not in the range A-D or a-d. In E, there cannot be more than 1 digit at the end of the string. Remember that an asterisk represents 0 or more of that character or rangle of characters.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". In terms of the Kleene Star, zz* = z*z = z+.<br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=589FSAs and Regular Expressions2018-09-12T18:19:43Z<p>Marc Brown: </p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state, so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
A Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. “ab” (a followed by b).<br />
::b. UNION. “aUb” (a or b). <br />
::c. CLOSURE. “a*” (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
Identities for Regular Expressions appear in the next section. The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A “most simplified” Regular Expression or FSA is not always well defined. <br />
<!--<br />
Most programming languages today have a package to handle Regular Expressions in order to do pattern matching algorithms more easily. Visual BASIC has the LIKE operator that is very easy to use. We will use these “basic” symbols in our category description.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
|?<br />
|Any single character<br />
|-<br />
|*<br />
|Zero or more of the preceding character<br />
|-<br />
|#<br />
|Any single digit<br />
|-<br />
|[ char-char,char,…]<br />
|Any inclusive range or list of characters<br />
|-<br />
|{![charlist]}<br />
|Any character not in a given range or list<br />
|}<br />
<br />
For example, the following strings either match or don’t match the pattern “[A-M][o-z][!a,e,I,o,u]?#.*”:<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!YES<br />
!NO<br />
!Why not?<br />
|-<br />
|App$5.java<br />
|Help1.<br />
| E is not in the range [o-z].<br />
|-<br />
|Dog&2.py<br />
|IoU$5<br />
|There is no . at the end.<br />
|-<br />
|LzyG3.txt<br />
|move6.py<br />
|The m is not in the range [A-M].<br />
|-<br />
|Hot90.<br />
|MaX7A.txt<br />
|The A is not a digit from 0 to 9.<br />
|}<br />
--><br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 are strings starting with oe or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 are strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s <br />
followed by some 0s. Choice A and E following this pattern.<br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (aUb)(ab*)(b*Ua)<br />
::B. (aab*Ubab*)a<br />
::C. aab*Ubab*UaabaUbab*a<br />
::D. aab*Ubab*Uaab*aUbab*a<br />
::E. a*Ub* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
<!--<br />
== Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "?[A-D]*[a-d]*#" ?<br />
<br />
::A. 8AAAabd4<br />
::B. MM5<br />
::C. AAAAAAAA7<br />
::D. Abcd9<br />
::E. &dd88<br />
::F. >BAD0<br />
<br />
'''Solution:'''<br />
<br />
The answer is A, C, D, and F. In B the character M is not in the range A-D or a-d. In E, there cannot be more than 1 digit at the end of the string. Remember that an asterisk represents 0 or more of that character or rangle of characters.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". <br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=584FSAs and Regular Expressions2018-09-12T07:55:09Z<p>Marc Brown: /* Problem 2 */</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state, so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
Just like [[Boolean Algebra]] is a convenient algebraic representation of [[Digital Electronics]] Circuits, a Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if the strings a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. “ab” (a followed by b).<br />
::b. UNION. “aUb” (a or b). <br />
::c. CLOSURE. “a*” (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
Identities for Regular Expressions appear in the next section. The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A “most simplified” Regular Expression or FSA is not always well defined. <br />
<!--<br />
Most programming languages today have a package to handle Regular Expressions in order to do pattern matching algorithms more easily. Visual BASIC has the LIKE operator that is very easy to use. We will use these “basic” symbols in our category description.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
|?<br />
|Any single character<br />
|-<br />
|*<br />
|Zero or more of the preceding character<br />
|-<br />
|#<br />
|Any single digit<br />
|-<br />
|[ char-char,char,…]<br />
|Any inclusive range or list of characters<br />
|-<br />
|{![charlist]}<br />
|Any character not in a given range or list<br />
|}<br />
<br />
For example, the following strings either match or don’t match the pattern “[A-M][o-z][!a,e,I,o,u]?#.*”:<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!YES<br />
!NO<br />
!Why not?<br />
|-<br />
|App$5.java<br />
|Help1.<br />
| E is not in the range [o-z].<br />
|-<br />
|Dog&2.py<br />
|IoU$5<br />
|There is no . at the end.<br />
|-<br />
|LzyG3.txt<br />
|move6.py<br />
|The m is not in the range [A-M].<br />
|-<br />
|Hot90.<br />
|MaX7A.txt<br />
|The A is not a digit from 0 to 9.<br />
|}<br />
--><br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
This Regular Expression parses strings described by the union of 00*1*1 and 11*0*0. The RE 00*1*1 are strings starting with oe or more 0s followed by one or more 1s: 01, 001, 0001111, and so on. The RE 11*0*0 are strings with one or more 1s followed by one or more 0s: 10, 1110, 1111100, and so on. In other words, strings of the form: 0s followed by some 1s; or 1s <br />
followed by some 0s. Choice A and E following this pattern.<br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (aUb)(ab*)(b*Ua)<br />
::B. (aab*Ubab*)a<br />
::C. aab*Ubab*UaabaUbab*a<br />
::D. aab*Ubab*Uaab*aUbab*a<br />
::E. a*Ub* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
<!--<br />
== Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "?[A-D]*[a-d]*#" ?<br />
<br />
::A. 8AAAabd4<br />
::B. MM5<br />
::C. AAAAAAAA7<br />
::D. Abcd9<br />
::E. &dd88<br />
::F. >BAD0<br />
<br />
'''Solution:'''<br />
<br />
The answer is A, C, D, and F. In B the character M is not in the range A-D or a-d. In E, there cannot be more than 1 digit at the end of the string. Remember that an asterisk represents 0 or more of that character or rangle of characters.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". <br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=583FSAs and Regular Expressions2018-09-12T07:47:00Z<p>Marc Brown: capitalized Regular Expression throughout</p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consisting of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state, so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
Just like [[Boolean Algebra]] is a convenient algebraic representation of [[Digital Electronics]] Circuits, a Regular Expression (RE) is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a Regular Expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if the strings a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. “ab” (a followed by b).<br />
::b. UNION. “aUb” (a or b). <br />
::c. CLOSURE. “a*” (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
Identities for Regular Expressions appear in the next section. The order of precedence for Regular Expression operators is: Kleene Star, concatenation, and then union. <br />
<br />
If we have a Regular Expression, then we can mechanically build an FSA to accept the strings which are generated by the Regular Expression. Conversely, if we have an FSA, we can mechanically develop a Regular Expression which will describe the strings which can be parsed by the FSA. For a given FSA or Regular Expression, there are many others which are equivalent to it. A “most simplified” Regular Expression or FSA is not always well defined. <br />
<!--<br />
Most programming languages today have a package to handle Regular Expressions in order to do pattern matching algorithms more easily. Visual BASIC has the LIKE operator that is very easy to use. We will use these “basic” symbols in our category description.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
|?<br />
|Any single character<br />
|-<br />
|*<br />
|Zero or more of the preceding character<br />
|-<br />
|#<br />
|Any single digit<br />
|-<br />
|[ char-char,char,…]<br />
|Any inclusive range or list of characters<br />
|-<br />
|{![charlist]}<br />
|Any character not in a given range or list<br />
|}<br />
<br />
For example, the following strings either match or don’t match the pattern “[A-M][o-z][!a,e,I,o,u]?#.*”:<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!YES<br />
!NO<br />
!Why not?<br />
|-<br />
|App$5.java<br />
|Help1.<br />
| E is not in the range [o-z].<br />
|-<br />
|Dog&2.py<br />
|IoU$5<br />
|There is no . at the end.<br />
|-<br />
|LzyG3.txt<br />
|move6.py<br />
|The m is not in the range [A-M].<br />
|-<br />
|Hot90.<br />
|MaX7A.txt<br />
|The A is not a digit from 0 to 9.<br />
|}<br />
--><br />
<br />
Typical problems in the category will include: translate an FSA to a Regular Expression; simplify a Regular Expression; determine which Regular Expressions or FSAs are equivalent; and determine which strings are accepted by either an FSA or a Regular Expression.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified Regular Expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following Regular Expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
Choice A uses the left hand pattern (00*1*1) and choice E uses the right hand pattern (11*0*0). <br />
Every string must start and end in the opposite digit so choices C and D don’t work. Choice B doesn’t work because all 1s and all 0s must be together.<br />
The correct answer is A and E. <br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (aUb)(ab*)(b*Ua)<br />
::B. (aab*Ubab*)a<br />
::C. aab*Ubab*UaabaUbab*a<br />
::D. aab*Ubab*Uaab*aUbab*a<br />
::E. a*Ub* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
<!--<br />
== Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "?[A-D]*[a-d]*#" ?<br />
<br />
::A. 8AAAabd4<br />
::B. MM5<br />
::C. AAAAAAAA7<br />
::D. Abcd9<br />
::E. &dd88<br />
::F. >BAD0<br />
<br />
'''Solution:'''<br />
<br />
The answer is A, C, D, and F. In B the character M is not in the range A-D or a-d. In E, there cannot be more than 1 digit at the end of the string. Remember that an asterisk represents 0 or more of that character or rangle of characters.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". <br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=582FSAs and Regular Expressions2018-09-12T07:29:18Z<p>Marc Brown: </p>
<hr />
<div>A Finite State Automaton (FSA) is a mathematical model of computation comprising: a finite number of ''states'', of which exactly one is ''active'' at any given time; ''transition rules'' to change<br />
the active state; an ''initial state''; and one more ''final states''. We can draw an FSA by representing each state as a circle; the final state as a double circle; the start state as the only state with an incoming arrow; and the transition rules as labeled-edges connecting the states. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
In this category, FSAs will be limited to parsing strings. That is, determining if a string is valid or not. <br />
<br />
= Basics =<br />
<br />
Here is a drawing of an FSA that is used to parse strings consists of x's and y's:<br />
<br />
<center><br />
[[File:fsa.svg|250px]]<br />
</center><br />
<br />
In the above FSA, there are three states: A, B, and C. The initial state is A; the final state is C. The only way to go from state A to B is by ''seeing'' the letter x. Once in state B, there are two transition rules: Seeing the letter y will cause the FSA to make C the active state, and seeing an x will keep B as the active state. State C is a final state, so if the string being parsed is completed and the FSA is in State C, the input string is said to be ''accepted'' by the FSA. In State C, seeing any additional letter y will keep the machine in state C. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy, xxyyyy). <br />
<br />
Just like [[Boolean Algebra]] is a convenient algebraic representation of [[Digital Electronics]] Circuits, a regular expression is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. <br />
<br />
The rules for forming a regular expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if the strings a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. “ab” (a followed by b).<br />
::b. UNION. “aUb” (a or b). <br />
::c. CLOSURE. “a*” (a repeated zero or more times). This is known as the Kleene Star.<br />
<br />
Identities for regular expressions appear in the next section. The order of precedence for regular expression operators is: Kleene Star, concatenation, and then union. <br />
<br />
If we have a regular expression, then we can mechanically build an FSA to accept the strings which are generated by the regular expression. Conversely, if we have an FSA, we can mechanically develop a regular expression which will describe the strings which can be parsed by the FSA. For a given FSA or regular expression, there are many others which are equivalent to it. A “most simplified” regular expression or FSA is not always well defined. <br />
<!--<br />
Most programming languages today have a package to handle Regular Expressions in order to do pattern matching algorithms more easily. Visual BASIC has the LIKE operator that is very easy to use. We will use these “basic” symbols in our category description.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
|?<br />
|Any single character<br />
|-<br />
|*<br />
|Zero or more of the preceding character<br />
|-<br />
|#<br />
|Any single digit<br />
|-<br />
|[ char-char,char,…]<br />
|Any inclusive range or list of characters<br />
|-<br />
|{![charlist]}<br />
|Any character not in a given range or list<br />
|}<br />
<br />
For example, the following strings either match or don’t match the pattern “[A-M][o-z][!a,e,I,o,u]?#.*”:<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!YES<br />
!NO<br />
!Why not?<br />
|-<br />
|App$5.java<br />
|Help1.<br />
| E is not in the range [o-z].<br />
|-<br />
|Dog&2.py<br />
|IoU$5<br />
|There is no . at the end.<br />
|-<br />
|LzyG3.txt<br />
|move6.py<br />
|The m is not in the range [A-M].<br />
|-<br />
|Hot90.<br />
|MaX7A.txt<br />
|The A is not a digit from 0 to 9.<br />
|}<br />
--><br />
<br />
Typical problems in the category will include: translate an FSA to a regular expression; simplify a regular expression (possibly to minimize the number of states or transitions); determine which regular expressions are equivalent; and determine which strings are accepted by either an FSA or a regular expression.<br />
<br />
= Regular Expression Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|-<br />
|2. aa* = a*a<br />
|-<br />
|3. aa* U λ = a*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|-<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
== Problem 1 ==<br />
<br />
Find a simplified regular expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Problem 2 ==<br />
<br />
Which of the following strings are accepted by the following regular expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
Choice A uses the left hand pattern (00*1*1) and choice E uses the right hand pattern (11*0*0). <br />
Every string must start and end in the opposite digit so choices C and D don’t work. Choice B doesn’t work because all 1s and all 0s must be together.<br />
The correct answer is A and E. <br />
<br />
== Problem 3 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (aUb)(ab*)(b*Ua)<br />
::B. (aab*Ubab*)a<br />
::C. aab*Ubab*UaabaUbab*a<br />
::D. aab*Ubab*Uaab*aUbab*a<br />
::E. a*Ub* <br />
<br />
'''Solution:'''<br />
<br />
Choice B can be discarded because it is the only RE whose strings '''must''' end with an a. Choice E can be discarded since it is the only RE that can accept a null string. Choices C and D are not equal. After expanding choice A, we must compare it to choices C and D. It is equal to choice D, but not to choice C. The only REs that are equivalent are choices A and D.<br />
<br />
<!--<br />
== Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "?[A-D]*[a-d]*#" ?<br />
<br />
::A. 8AAAabd4<br />
::B. MM5<br />
::C. AAAAAAAA7<br />
::D. Abcd9<br />
::E. &dd88<br />
::F. >BAD0<br />
<br />
'''Solution:'''<br />
<br />
The answer is A, C, D, and F. In B the character M is not in the range A-D or a-d. In E, there cannot be more than 1 digit at the end of the string. Remember that an asterisk represents 0 or more of that character or rangle of characters.<br />
--><br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". <br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=File:Fsa.svg&diff=581File:Fsa.svg2018-09-12T07:23:12Z<p>Marc Brown: </p>
<hr />
<div></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Main_Page&diff=580Main Page2018-09-12T05:59:23Z<p>Marc Brown: </p>
<hr />
<div>Welcome to the wiki describing the topics covered in the short programs section of the [http://www.acsl.org ACSL] contests.<br />
<br />
If you'd like to contribute to this wiki - and we'd love to improve it - please shoot us an email requesting an account. Conversely, if we've linked to your material (especially YouTube videos) that you'd prefer that we do not reference, let us know and we will promptly remove those links.<br />
<br />
Categories covered:<br />
<br />
* [[Assembly Language Programming]] <br />
* [[Bit-String Flicking]] <br />
* [[Boolean Algebra]]<br />
* [[Computer Number Systems]]<br />
* [[Data Structures]]<br />
* [[Digital Electronics]] <br />
* [[FSAs and Regular Expressions]] <br />
* [[Graph Theory]]<br />
* [[LISP]] <br />
* [[Prefix/Infix/Postfix Notation]]<br />
* [[Recursive Functions]]<br />
* [[What Does This Program Do?]]<br />
* [http://www.acsl.org/categories/C1Elem-ComputerNumberSystems.pdf Elementary Division: Computer Number Systems (Contest 1)]<br />
* [http://www.acsl.org/categories/C2Elem-Prefix-Postfix-InfixNotation.pdf Elementary Division: Prefix-Postfix-Infix Notation (Contest 2)]]<br />
* [http://www.acsl.org/categories/C3Elem-BooleanAlgebra.pdf Elementary Division: Boolean Algebra (Contest 3)]<br />
* [http://www.acsl.org/categories/C4Elem-GraphTheory.pdf Elementary Division: Graph Theory (Contest 4)]<br />
<br />
== Getting started ==<br />
* [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software<br />
* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]<br />
* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=579FSAs and Regular Expressions2018-09-12T05:58:46Z<p>Marc Brown: Marc Brown moved page Regular Expressions to FSAs and Regular Expressions without leaving a redirect</p>
<hr />
<div>A Finite State Automation (FSA) has four components: an input alphabet (those letters or strings which are legal inputs); a set of transition rules to advance from state to state (given a current state and an element of the input alphabet, what is the next state); a unique start state; and one or more final states. We can draw the FSA, as shown below, by representing each state as a circular node; the final state as a double circle; the start state as the only node with an incoming arrow; and the transition rules by the strings on the edges connecting the nodes. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
[[File:fsa_1.png]]<br />
<br />
If there is a path from the start state to a final state by which an input string can be parsed, then the input string is said to be “accepted” by the FSA. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy). <br />
<br />
= Definitions =<br />
<br />
Just like [[Boolean Algebra]] is a convenient algebraic representation of [[Digital Electronics]] Circuits, a regular expression is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. The regular expression for the second FSA is extremely complex! The following simple FSAs and REs illustrate the correspondence:<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|[[File:fsas_2-3.png|512px]]<br />
|-<br />
|ab*c ___________________ (aUb)c or acUbc<br />
|}<br />
<br />
The rules for forming a regular expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if the strings a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. “ab” (a followed by b).<br />
::b. UNION. “aUb” (a or b). <br />
::c. CLOSURE. “a*” (a repeated zero or more times).<br />
<br />
If we have a regular expression, then we can mechanically build an FSA to accept the strings which are generated by the regular expression. Conversely, if we have an FSA, we can mechanically develop a regular expression which will describe the strings which can be parsed by the FSA. For a given FSA or regular expression, there are many others which are equivalent to it. A “most simplified” regular expression or FSA is not always well defined. <br />
<br />
Identities for regular expressions appear below. The order of precedence for regular expression operators is: Kleene Star, concatenation, and then union. The Kleene Star binds from right to left; concatenation and union both bind from left to right. <br />
<br />
Most programming languages today have a package to handle Regular Expressions in order to do pattern matching algorithms more easily. Visual BASIC has the LIKE operator that is very easy to use. We will use these “basic” symbols in our category description.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
|?<br />
|Any single character<br />
|-<br />
|*<br />
|Zero or more of the preceding character<br />
|-<br />
|#<br />
|Any single digit<br />
|-<br />
|[ char-char,char,…]<br />
|Any inclusive range or list of characters<br />
|-<br />
|{![charlist]}<br />
|Any character not in a given range or list<br />
|}<br />
<br />
For example, the following strings either match or don’t match the pattern “[A-M][o-z][!a,e,I,o,u]?#.*”:<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!YES<br />
!NO<br />
!Why not?<br />
|-<br />
|App$5.java<br />
|Help1.<br />
| E is not in the range [o-z].<br />
|-<br />
|Dog&2.py<br />
|IoU$5<br />
|There is no . at the end.<br />
|-<br />
|LzyG3.txt<br />
|move6.py<br />
|The m is not in the range [A-M].<br />
|-<br />
|Hot90.<br />
|MaX7A.txt<br />
|The A is not a digit from 0 to 9.<br />
|}<br />
<br />
Typical problems in the category will include: translate an FSA to a regular expression; simplify a regular expression (possibly to minimize the number of states or transitions); determine which regular expressions are equivalent; and determine which strings are accepted by either an FSA or a regular expression.<br />
<br />
= Basic Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|2. aa* = a*a<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|3. aa* U λ = a*<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
== Sample Problem 1 ==<br />
<br />
Find a simplified regular expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Sample Problem 2 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (aUb)(ab*)(b*Ua)<br />
::B. (aab*Ubab*)a<br />
::C. aab*Ubab*UaabaUbab*a<br />
::D. aab*Ubab*Uaab*aUbab*a<br />
::E. a*Ub* <br />
<br />
'''Solution:'''<br />
<br />
On first inspection, B can be discarded because it is the only RE whose strings must end in an a. E can also be discarded since it is the only RE that can accept a null string. C and D are not equal. After expanding A, we must compare it to C and D. It is equal to D, but not to C. A and D.<br />
<br />
== Sample Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "?[A-D]*[a-d]*#" ?<br />
<br />
::A. 8AAAabd4<br />
::B. MM5<br />
::C. AAAAAAAA7<br />
::D. Abcd9<br />
::E. &dd88<br />
::F. >BAD0<br />
<br />
'''Solution:'''<br />
<br />
The answer is A, C, D, and F. In B the character M is not in the range A-D or a-d. In E, there cannot be more than 1 digit at the end of the string. Remember that an asterisk represents 0 or more of that character or rangle of characters.<br />
<br />
== Sample Problem 4 ==<br />
<br />
Which of the following strings are accepted by the following regular expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
The answer is A and E. A uses the left hand pattern and E uses the right hand pattern. Every string must stat and end in the opposite digit so C and D don’t work. B doesn’t work because all 1’s and all 0’s must be together.<br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". <br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=FSAs_and_Regular_Expressions&diff=578FSAs and Regular Expressions2018-09-12T05:57:57Z<p>Marc Brown: /* Video Resources */</p>
<hr />
<div>A Finite State Automation (FSA) has four components: an input alphabet (those letters or strings which are legal inputs); a set of transition rules to advance from state to state (given a current state and an element of the input alphabet, what is the next state); a unique start state; and one or more final states. We can draw the FSA, as shown below, by representing each state as a circular node; the final state as a double circle; the start state as the only node with an incoming arrow; and the transition rules by the strings on the edges connecting the nodes. When labels are assigned to states, they appear inside the circle representing the state. <br />
<br />
[[File:fsa_1.png]]<br />
<br />
If there is a path from the start state to a final state by which an input string can be parsed, then the input string is said to be “accepted” by the FSA. The FSA above will accept strings composed of one or more x’s followed by one or more y’s (e.g., xy, xxy, xxxyy, xyyy). <br />
<br />
= Definitions =<br />
<br />
Just like [[Boolean Algebra]] is a convenient algebraic representation of [[Digital Electronics]] Circuits, a regular expression is an algebraic representation of an FSA. For example, the regular expression corresponding to the first FSA given above is xx*yy*. The regular expression for the second FSA is extremely complex! The following simple FSAs and REs illustrate the correspondence:<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|[[File:fsas_2-3.png|512px]]<br />
|-<br />
|ab*c ___________________ (aUb)c or acUbc<br />
|}<br />
<br />
The rules for forming a regular expression (RE) are as follows:<br />
:1. The null string (λ) is a RE.<br />
:2. If the string a is in the input alphabet, then it is a RE.<br />
:3. if the strings a and b are both REs, then so are the strings built up using the following rules:<br />
::a. CONCATENATION. “ab” (a followed by b).<br />
::b. UNION. “aUb” (a or b). <br />
::c. CLOSURE. “a*” (a repeated zero or more times).<br />
<br />
If we have a regular expression, then we can mechanically build an FSA to accept the strings which are generated by the regular expression. Conversely, if we have an FSA, we can mechanically develop a regular expression which will describe the strings which can be parsed by the FSA. For a given FSA or regular expression, there are many others which are equivalent to it. A “most simplified” regular expression or FSA is not always well defined. <br />
<br />
Identities for regular expressions appear below. The order of precedence for regular expression operators is: Kleene Star, concatenation, and then union. The Kleene Star binds from right to left; concatenation and union both bind from left to right. <br />
<br />
Most programming languages today have a package to handle Regular Expressions in order to do pattern matching algorithms more easily. Visual BASIC has the LIKE operator that is very easy to use. We will use these “basic” symbols in our category description.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!Pattern<br />
!Description<br />
|-<br />
|?<br />
|Any single character<br />
|-<br />
|*<br />
|Zero or more of the preceding character<br />
|-<br />
|#<br />
|Any single digit<br />
|-<br />
|[ char-char,char,…]<br />
|Any inclusive range or list of characters<br />
|-<br />
|{![charlist]}<br />
|Any character not in a given range or list<br />
|}<br />
<br />
For example, the following strings either match or don’t match the pattern “[A-M][o-z][!a,e,I,o,u]?#.*”:<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!YES<br />
!NO<br />
!Why not?<br />
|-<br />
|App$5.java<br />
|Help1.<br />
| E is not in the range [o-z].<br />
|-<br />
|Dog&2.py<br />
|IoU$5<br />
|There is no . at the end.<br />
|-<br />
|LzyG3.txt<br />
|move6.py<br />
|The m is not in the range [A-M].<br />
|-<br />
|Hot90.<br />
|MaX7A.txt<br />
|The A is not a digit from 0 to 9.<br />
|}<br />
<br />
Typical problems in the category will include: translate an FSA to a regular expression; simplify a regular expression (possibly to minimize the number of states or transitions); determine which regular expressions are equivalent; and determine which strings are accepted by either an FSA or a regular expression.<br />
<br />
= Basic Identities =<br />
<br />
{| Class="wikitable"<br />
|-<br />
|1. (a*)* = a*<br />
|5. a(ba)* = (ab)*a<br />
|-<br />
|2. aa* = a*a<br />
|6. (a U b)* = (a* U b*)*<br />
|-<br />
|3. aa* U λ = a*<br />
|7. (a U b)* = (a*b*)*<br />
|-<br />
|4. a(b U c) = ab U ac<br />
|8. (a U b)* = a*(ba*)*<br />
|}<br />
<br />
= Sample Problems =<br />
<br />
== Sample Problem 1 ==<br />
<br />
Find a simplified regular expression for the following FSA:<br />
<br />
[[File:fsa_s1.png]]<br />
<br />
'''Solution:'''<br />
<br />
The expression 01*01 is read directly from the FSA. It is in its most simplified form.<br />
<br />
== Sample Problem 2 ==<br />
<br />
Which, if any, of the following Regular Expressions are equivalent?<br />
::A. (aUb)(ab*)(b*Ua)<br />
::B. (aab*Ubab*)a<br />
::C. aab*Ubab*UaabaUbab*a<br />
::D. aab*Ubab*Uaab*aUbab*a<br />
::E. a*Ub* <br />
<br />
'''Solution:'''<br />
<br />
On first inspection, B can be discarded because it is the only RE whose strings must end in an a. E can also be discarded since it is the only RE that can accept a null string. C and D are not equal. After expanding A, we must compare it to C and D. It is equal to D, but not to C. A and D.<br />
<br />
== Sample Problem 3 ==<br />
<br />
Which of the following strings match the regular expression pattern "?[A-D]*[a-d]*#" ?<br />
<br />
::A. 8AAAabd4<br />
::B. MM5<br />
::C. AAAAAAAA7<br />
::D. Abcd9<br />
::E. &dd88<br />
::F. >BAD0<br />
<br />
'''Solution:'''<br />
<br />
The answer is A, C, D, and F. In B the character M is not in the range A-D or a-d. In E, there cannot be more than 1 digit at the end of the string. Remember that an asterisk represents 0 or more of that character or rangle of characters.<br />
<br />
== Sample Problem 4 ==<br />
<br />
Which of the following strings are accepted by the following regular expression "00*1*1U11*0*0" ?<br />
<br />
::A. 0000001111111<br />
::B. 1010101010<br />
::C. 1111111<br />
::D. 0110<br />
::E. 10 <br />
<br />
'''Solution:'''<br />
<br />
The answer is A and E. A uses the left hand pattern and E uses the right hand pattern. Every string must stat and end in the opposite digit so C and D don’t work. B doesn’t work because all 1’s and all 0’s must be together.<br />
<br />
= Video Resources =<br />
<br />
Nice two-part video showing the relationship between FSAs and REs. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/GwsU2LPs85U</youtube><br />
| [https://youtu.be/GwsU2LPs85U ''1 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
<br />
| <youtube width="300" height="180">https://youtu.be/shN_kHBFOUE</youtube><br />
| [https://youtu.be/shN_kHBFOUE ''2 - Convert Regular Expression to Finite-State Automaton'' ('''Barry Brown''')]<br />
<br />
This video uses the symbol "+" to mean "1 or more matches of the previous term". For example, "ab+" is the same as "abb*". <br />
|}<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=577Data Structures2018-09-12T03:05:36Z<p>Marc Brown: /* Stacks and Queues */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is found in the list of items and if not, which item is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the list.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire courses devoted to fundamental data structures. Implementation varies by computer language, but for our purposes, they can all be represented as a list of items that might contain duplicates. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form PUSH("A") puts the key "A" at the top of the stack; the command “X = POP()” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A command of the form PUSH("A") puts the key "A" at the top of the queue; the command “X = POP()” removes the item from the bottom of the queue and stores its value into variable X. If the queue was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up". Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH("A")<br />
PUSH("M")<br />
PUSH("E")<br />
X = POP()<br />
PUSH("R")<br />
X = POP()<br />
PUSH("I")<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
PUSH("C")<br />
PUSH("A")<br />
PUSH("N")<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes.<br />
<br />
=== Pre-2018 Syntax ===<br />
<br />
ACSL Contests pre-2018 used a slightly different, and more liberal, syntax. Consider the following sequence on a stack:<br />
<br />
<syntaxhighlight><br />
PUSH(A)<br />
PUSH(B)<br />
PUSH(C)<br />
POP(X)<br />
POP(Z)<br />
</syntaxhighlight><br />
<br />
After the 5 operations, the stack would be left with A as the only element on the stack, the value of C in variable X, and the value of B in variable Z. <br />
<br />
Were the above operations applied to a queue, the queue would be left with C; variable X would contain A; and variable Z would contain B.<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
<center><br />
[[File:bst-american.svg|200px]]<br />
</center><br />
<br />
The ''root'' of the resulting tree is the node containing the key A. Our ACSL convention places duplicate keys into the tree as if they were less than their equal key. (In some textbooks and software libraries, duplicate keys may be considered larger than their equal key.) The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. Our ACSL convention is that an ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, an external node is synonymous with a leaf node.) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
A binary search tree can support the operations insert, delete, and search. Moreover, it handles the operations efficiently for ''balanced'' trees. In a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1,000,000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y which places all of the other letters on the right side of the root "A". This is very unbalanced; therefore, sophisticated algorithms can be used to maintain balanced trees. Binary search trees are “dynamic” data structures that can support many operations in any order and introduces or removes nodes as needed. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x < p’s key)<br />
p = p’s left child<br />
else if (x > p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
<center><br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
</center><br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve the smallest item only. These insert and delete operations can be done in a guaranteed time proportional to the log (base 2) of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is less than or equal to both of its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right.<br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
<center><br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
</center><br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the smaller child in order to ensure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, A ''max-heap'' is also possible and is common in practice. An efficient implementation of a heap uses an array that can be understood conceptually by using a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. After the following operations are performed, what is the value of Z?<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
Y = POP()<br />
X = POP()<br />
PUSH(X-Y)<br />
Z = POP() <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP stores 8 in Y. The POP stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, the last POP removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
<br />
<center><br />
[[File:heap-programming.svg|200px]]<br />
</center><br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAM. What is the internal path length? <br />
<br />
'''Solution:''' When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, and A and M have a depth of 3. Therefore, the internal path length is 2*1 + 2*2 + 2*3 = 12. Here is the tree:<br />
<br />
<center><br />
[[File:bst-program.svg|200px]]<br />
</center><br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=576Data Structures2018-09-10T06:03:13Z<p>Marc Brown: /* Problem 1 */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is found in the list of items and if not, which item is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the list.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire courses devoted to fundamental data structures. Implementation varies by computer language, but for our purposes, they can all be represented as a list of items that might contain duplicates. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form PUSH("A") puts the key "A" at the top of the stack; the command “X = POP()” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A command of the form PUSH("A") puts the key "A" at the top of the queue; the command “X = POP()” removes the item from the bottom of the queue and stores its value into variable X. If the queue was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up". Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH("A")<br />
PUSH("M")<br />
PUSH("E")<br />
X = POP()<br />
PUSH("R")<br />
X = POP()<br />
PUSH("I")<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
PUSH("C")<br />
PUSH("A")<br />
PUSH("N")<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes.<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
<center><br />
[[File:bst-american.svg|200px]]<br />
</center><br />
<br />
The ''root'' of the resulting tree is the node containing the key A. Our ACSL convention places duplicate keys into the tree as if they were less than their equal key. (In some textbooks and software libraries, duplicate keys may be considered larger than their equal key.) The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. Our ACSL convention is that an ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, an external node is synonymous with a leaf node.) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
A binary search tree can support the operations insert, delete, and search. Moreover, it handles the operations efficiently for ''balanced'' trees. In a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1,000,000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y which places all of the other letters on the right side of the root "A". This is very unbalanced; therefore, sophisticated algorithms can be used to maintain balanced trees. Binary search trees are “dynamic” data structures that can support many operations in any order and introduces or removes nodes as needed. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x < p’s key)<br />
p = p’s left child<br />
else if (x > p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
<center><br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
</center><br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve the smallest item only. These insert and delete operations can be done in a guaranteed time proportional to the log (base 2) of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is less than or equal to both of its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right.<br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
<center><br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
</center><br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the smaller child in order to ensure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, A ''max-heap'' is also possible and is common in practice. An efficient implementation of a heap uses an array that can be understood conceptually by using a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. After the following operations are performed, what is the value of Z?<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
Y = POP()<br />
X = POP()<br />
PUSH(X-Y)<br />
Z = POP() <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP stores 8 in Y. The POP stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, the last POP removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
<br />
<center><br />
[[File:heap-programming.svg|200px]]<br />
</center><br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAM. What is the internal path length? <br />
<br />
'''Solution:''' When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, and A and M have a depth of 3. Therefore, the internal path length is 2*1 + 2*2 + 2*3 = 12. Here is the tree:<br />
<br />
<center><br />
[[File:bst-program.svg|200px]]<br />
</center><br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=575Data Structures2018-09-10T06:01:41Z<p>Marc Brown: /* Priority Queues */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is found in the list of items and if not, which item is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the list.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire courses devoted to fundamental data structures. Implementation varies by computer language, but for our purposes, they can all be represented as a list of items that might contain duplicates. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form PUSH("A") puts the key "A" at the top of the stack; the command “X = POP()” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A command of the form PUSH("A") puts the key "A" at the top of the queue; the command “X = POP()” removes the item from the bottom of the queue and stores its value into variable X. If the queue was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up". Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH("A")<br />
PUSH("M")<br />
PUSH("E")<br />
X = POP()<br />
PUSH("R")<br />
X = POP()<br />
PUSH("I")<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
PUSH("C")<br />
PUSH("A")<br />
PUSH("N")<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes.<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
<center><br />
[[File:bst-american.svg|200px]]<br />
</center><br />
<br />
The ''root'' of the resulting tree is the node containing the key A. Our ACSL convention places duplicate keys into the tree as if they were less than their equal key. (In some textbooks and software libraries, duplicate keys may be considered larger than their equal key.) The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. Our ACSL convention is that an ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, an external node is synonymous with a leaf node.) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
A binary search tree can support the operations insert, delete, and search. Moreover, it handles the operations efficiently for ''balanced'' trees. In a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1,000,000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y which places all of the other letters on the right side of the root "A". This is very unbalanced; therefore, sophisticated algorithms can be used to maintain balanced trees. Binary search trees are “dynamic” data structures that can support many operations in any order and introduces or removes nodes as needed. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x < p’s key)<br />
p = p’s left child<br />
else if (x > p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
<center><br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
</center><br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve the smallest item only. These insert and delete operations can be done in a guaranteed time proportional to the log (base 2) of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is less than or equal to both of its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right.<br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
<center><br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
</center><br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the smaller child in order to ensure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, A ''max-heap'' is also possible and is common in practice. An efficient implementation of a heap uses an array that can be understood conceptually by using a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. What is the value of Z when these operations are performed:<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
Y = POP()<br />
X = POP()<br />
PUSH(X-Y)<br />
Z = POP() <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP() stores 8 in Y. The POP() stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, the last POP() removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
<br />
<center><br />
[[File:heap-programming.svg|200px]]<br />
</center><br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAM. What is the internal path length? <br />
<br />
'''Solution:''' When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, and A and M have a depth of 3. Therefore, the internal path length is 2*1 + 2*2 + 2*3 = 12. Here is the tree:<br />
<br />
<center><br />
[[File:bst-program.svg|200px]]<br />
</center><br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=574Data Structures2018-09-10T06:01:13Z<p>Marc Brown: /* Trees */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is found in the list of items and if not, which item is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the list.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire courses devoted to fundamental data structures. Implementation varies by computer language, but for our purposes, they can all be represented as a list of items that might contain duplicates. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form PUSH("A") puts the key "A" at the top of the stack; the command “X = POP()” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A command of the form PUSH("A") puts the key "A" at the top of the queue; the command “X = POP()” removes the item from the bottom of the queue and stores its value into variable X. If the queue was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up". Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH("A")<br />
PUSH("M")<br />
PUSH("E")<br />
X = POP()<br />
PUSH("R")<br />
X = POP()<br />
PUSH("I")<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
PUSH("C")<br />
PUSH("A")<br />
PUSH("N")<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes.<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
<center><br />
[[File:bst-american.svg|200px]]<br />
</center><br />
<br />
The ''root'' of the resulting tree is the node containing the key A. Our ACSL convention places duplicate keys into the tree as if they were less than their equal key. (In some textbooks and software libraries, duplicate keys may be considered larger than their equal key.) The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. Our ACSL convention is that an ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, an external node is synonymous with a leaf node.) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
A binary search tree can support the operations insert, delete, and search. Moreover, it handles the operations efficiently for ''balanced'' trees. In a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1,000,000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y which places all of the other letters on the right side of the root "A". This is very unbalanced; therefore, sophisticated algorithms can be used to maintain balanced trees. Binary search trees are “dynamic” data structures that can support many operations in any order and introduces or removes nodes as needed. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x < p’s key)<br />
p = p’s left child<br />
else if (x > p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
<center><br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
</center><br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve the smallest item only. These insert and delete operations can be done in a guaranteed time proportional to the log (base 2) of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is less than or equal to both of its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right.<br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the smaller child in order to ensure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, A ''max-heap'' is also possible and is common in practice. An efficient implementation of a heap uses an array that can be understood conceptually by using a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. What is the value of Z when these operations are performed:<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
Y = POP()<br />
X = POP()<br />
PUSH(X-Y)<br />
Z = POP() <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP() stores 8 in Y. The POP() stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, the last POP() removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
<br />
<center><br />
[[File:heap-programming.svg|200px]]<br />
</center><br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAM. What is the internal path length? <br />
<br />
'''Solution:''' When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, and A and M have a depth of 3. Therefore, the internal path length is 2*1 + 2*2 + 2*3 = 12. Here is the tree:<br />
<br />
<center><br />
[[File:bst-program.svg|200px]]<br />
</center><br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=573Data Structures2018-09-10T06:00:18Z<p>Marc Brown: /* Problem 3 */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is found in the list of items and if not, which item is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the list.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire courses devoted to fundamental data structures. Implementation varies by computer language, but for our purposes, they can all be represented as a list of items that might contain duplicates. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form PUSH("A") puts the key "A" at the top of the stack; the command “X = POP()” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A command of the form PUSH("A") puts the key "A" at the top of the queue; the command “X = POP()” removes the item from the bottom of the queue and stores its value into variable X. If the queue was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up". Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH("A")<br />
PUSH("M")<br />
PUSH("E")<br />
X = POP()<br />
PUSH("R")<br />
X = POP()<br />
PUSH("I")<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
PUSH("C")<br />
PUSH("A")<br />
PUSH("N")<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes.<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
[[File:bst-american.svg|200px]]<br />
<br />
The ''root'' of the resulting tree is the node containing the key A. Our ACSL convention places duplicate keys into the tree as if they were less than their equal key. (In some textbooks and software libraries, duplicate keys may be considered larger than their equal key.) The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. Our ACSL convention is that an ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, an external node is synonymous with a leaf node.) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
A binary search tree can support the operations insert, delete, and search. Moreover, it handles the operations efficiently for ''balanced'' trees. In a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1,000,000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y which places all of the other letters on the right side of the root "A". This is very unbalanced; therefore, sophisticated algorithms can be used to maintain balanced trees. Binary search trees are “dynamic” data structures that can support many operations in any order and introduces or removes nodes as needed. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x < p’s key)<br />
p = p’s left child<br />
else if (x > p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve the smallest item only. These insert and delete operations can be done in a guaranteed time proportional to the log (base 2) of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is less than or equal to both of its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right.<br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the smaller child in order to ensure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, A ''max-heap'' is also possible and is common in practice. An efficient implementation of a heap uses an array that can be understood conceptually by using a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. What is the value of Z when these operations are performed:<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
Y = POP()<br />
X = POP()<br />
PUSH(X-Y)<br />
Z = POP() <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP() stores 8 in Y. The POP() stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, the last POP() removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
<br />
<center><br />
[[File:heap-programming.svg|200px]]<br />
</center><br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAM. What is the internal path length? <br />
<br />
'''Solution:''' When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, and A and M have a depth of 3. Therefore, the internal path length is 2*1 + 2*2 + 2*3 = 12. Here is the tree:<br />
<br />
<center><br />
[[File:bst-program.svg|200px]]<br />
</center><br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=572Data Structures2018-09-10T05:59:34Z<p>Marc Brown: /* Problem 2 */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is found in the list of items and if not, which item is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the list.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire courses devoted to fundamental data structures. Implementation varies by computer language, but for our purposes, they can all be represented as a list of items that might contain duplicates. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form PUSH("A") puts the key "A" at the top of the stack; the command “X = POP()” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A command of the form PUSH("A") puts the key "A" at the top of the queue; the command “X = POP()” removes the item from the bottom of the queue and stores its value into variable X. If the queue was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up". Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH("A")<br />
PUSH("M")<br />
PUSH("E")<br />
X = POP()<br />
PUSH("R")<br />
X = POP()<br />
PUSH("I")<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
PUSH("C")<br />
PUSH("A")<br />
PUSH("N")<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes.<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
[[File:bst-american.svg|200px]]<br />
<br />
The ''root'' of the resulting tree is the node containing the key A. Our ACSL convention places duplicate keys into the tree as if they were less than their equal key. (In some textbooks and software libraries, duplicate keys may be considered larger than their equal key.) The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. Our ACSL convention is that an ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, an external node is synonymous with a leaf node.) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
A binary search tree can support the operations insert, delete, and search. Moreover, it handles the operations efficiently for ''balanced'' trees. In a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1,000,000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y which places all of the other letters on the right side of the root "A". This is very unbalanced; therefore, sophisticated algorithms can be used to maintain balanced trees. Binary search trees are “dynamic” data structures that can support many operations in any order and introduces or removes nodes as needed. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x < p’s key)<br />
p = p’s left child<br />
else if (x > p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve the smallest item only. These insert and delete operations can be done in a guaranteed time proportional to the log (base 2) of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is less than or equal to both of its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right.<br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the smaller child in order to ensure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, A ''max-heap'' is also possible and is common in practice. An efficient implementation of a heap uses an array that can be understood conceptually by using a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. What is the value of Z when these operations are performed:<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
Y = POP()<br />
X = POP()<br />
PUSH(X-Y)<br />
Z = POP() <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP() stores 8 in Y. The POP() stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, the last POP() removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
<br />
<center><br />
[[File:heap-programming.svg|200px]]<br />
</center><br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAM. What is the internal path length? <br />
<br />
Solution: When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, and A and M have a depth of 3. Therefore, the internal path length is 2*1 + 2*2 + 2*3 = 12. Here is the tree:<br />
<br />
[[File:bst-program.svg|200px]]<br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=571Data Structures2018-09-10T05:59:04Z<p>Marc Brown: /* Problem 2 */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is found in the list of items and if not, which item is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the list.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire courses devoted to fundamental data structures. Implementation varies by computer language, but for our purposes, they can all be represented as a list of items that might contain duplicates. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form PUSH("A") puts the key "A" at the top of the stack; the command “X = POP()” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A command of the form PUSH("A") puts the key "A" at the top of the queue; the command “X = POP()” removes the item from the bottom of the queue and stores its value into variable X. If the queue was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up". Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH("A")<br />
PUSH("M")<br />
PUSH("E")<br />
X = POP()<br />
PUSH("R")<br />
X = POP()<br />
PUSH("I")<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
X = POP()<br />
PUSH("C")<br />
PUSH("A")<br />
PUSH("N")<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes.<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
[[File:bst-american.svg|200px]]<br />
<br />
The ''root'' of the resulting tree is the node containing the key A. Our ACSL convention places duplicate keys into the tree as if they were less than their equal key. (In some textbooks and software libraries, duplicate keys may be considered larger than their equal key.) The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. Our ACSL convention is that an ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, an external node is synonymous with a leaf node.) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
A binary search tree can support the operations insert, delete, and search. Moreover, it handles the operations efficiently for ''balanced'' trees. In a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1,000,000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y which places all of the other letters on the right side of the root "A". This is very unbalanced; therefore, sophisticated algorithms can be used to maintain balanced trees. Binary search trees are “dynamic” data structures that can support many operations in any order and introduces or removes nodes as needed. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x < p’s key)<br />
p = p’s left child<br />
else if (x > p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve the smallest item only. These insert and delete operations can be done in a guaranteed time proportional to the log (base 2) of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is less than or equal to both of its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right.<br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the smaller child in order to ensure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, A ''max-heap'' is also possible and is common in practice. An efficient implementation of a heap uses an array that can be understood conceptually by using a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. What is the value of Z when these operations are performed:<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
Y = POP()<br />
X = POP()<br />
PUSH(X-Y)<br />
Z = POP() <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP() stores 8 in Y. The POP() stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, the last POP() removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
<br />
[[File:heap-programming.svg|200px]]<br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAM. What is the internal path length? <br />
<br />
Solution: When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, and A and M have a depth of 3. Therefore, the internal path length is 2*1 + 2*2 + 2*3 = 12. Here is the tree:<br />
<br />
[[File:bst-program.svg|200px]]<br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is a clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Prefix/Infix/Postfix_Notation&diff=569Prefix/Infix/Postfix Notation2018-09-09T09:42:14Z<p>Marc Brown: /* Context */</p>
<hr />
<div>The expression $5+\large{8\over{3-1}}$ clearly has a value of 9. It is written in ''infix'' notation as $5+8/(3-1)$. The value of an ''infix'' version is well-defined because there is a well-established order of precedence in mathematics: We first evaluate the parentheses (3-1=2); then, because division has higher precedence that subtraction, we next do 8/2=4. And finally, 5+4=9. The order of precedence is often given the mnemonic of '''Please excuse my dear Aunt Sue''', or '''PEMDAS''': '''p'''arentheses, '''e'''xponentiation, '''m'''ultiplication/'''d'''ivision, and '''a'''ddition/''''s'''ubtraction. Multiplication and division have the same level of precedence; addition and subtraction also have the same level of precedence. Terms with equals precedence are evaluated from left-to-right [https://en.wikipedia.org/wiki/Order_of_operations wikipedia].<br />
<br />
The algorithm to evaluate an ''infix'' expression is complex, as it must address the order of precedence. Two alternative notations have been developed which lend themselves to simple computer algorithms for evaluating expressions. In ''prefix'' notation, each operator is placed before its operands . The expression above would be <syntaxhighlight lang="python" inline>+ 5 / 8 - 3 1</syntaxhighlight>. In ''postfix'' notation, each operator is placed after its operand. The expression above is <syntaxhighlight lang="python" inline>5 8 3 1 - / +</syntaxhighlight>. In ''prefix'' and ''postfix'' notations, there is no notion of order of precedence, nor are there any parentheses. The evaluation is the same regardless of the operators. <br />
<br />
Problems in this category ask to convert between prefix, infix, and postfix, or to evaluate an expression in prefix or postfix.<br />
<br />
== Converting Expressions ==<br />
<br />
An algorithm for converting from infix to prefix (postfix) is as follows:<br />
* Fully parenthesize the infix expression. It should now consist solely of “terms”: a binary operator sandwiched between two operands.<br />
* Write down the operands in the same order that they appear in the infix expression.<br />
* Look at each term in the infix expression in the order that one would evaluate them, i.e., inner-most parenthesis to outer-most and left to right among terms of the same depth.<br />
* For each term, write down the operand before (after) the operators. <br />
<br />
One way to convert from prefix (postfix) to infix is to make repeated scans through the expression. <br />
Each scan, find an operator with two adjacent operators and replace it with a parenthesized infix expression. <br />
This is not the most efficient algorithm, but works well for a human.<br />
<br />
A quick check for determining whether a conversion is correct is to convert the result back into the original format. <br />
<br />
== Context ==<br />
<br />
''Prefix'' and ''postfix'' notation is also known as [https://en.wikipedia.org/wiki/Polish_notation ''Polish'' and ''Reverse Polish'' notation], respectively.<br />
<br />
== Examples ==<br />
<br />
=== Infix to Prefix ===<br />
<br />
<br />
The following sequence of steps illustrates converting $X=\left(AB-{C\over{D}}\right)^E$ from infix to prefix:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!(X = (((A * B) - (C / D)) ↑ E)) <br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" |X A B C D E <br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>* A B</syntaxhighlight> C D E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>* A B</syntaxhighlight> <syntaxhighlight lang="python" inline>/ C D</syntaxhighlight> E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>- * A B / C D</syntaxhighlight> E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>↑- * A B / C D E</syntaxhighlight><br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | <syntaxhighlight lang="python" inline>= X ↑ - * A B / C D E</syntaxhighlight><br />
|}<br />
<br />
=== Infix to Postfix ===<br />
<br />
<br />
The following sequence of steps illustrates converting $X=\left(AB-{C\over{D}}\right)^E$ from infix to postfix:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!(X = (((A * B) - (C / D)) ↑ E))<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" |X A B C D E <br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>A B *</syntaxhighlight> C D E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>A B *</syntaxhighlight> <syntaxhighlight lang="python" inline>C D /</syntaxhighlight> E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>A B * C D / -</syntaxhighlight> E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>A B * C D / - E ↑</syntaxhighlight><br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | <syntaxhighlight lang="python" inline> X A B * C D / - E ↑ =</syntaxhighlight><br />
|}<br />
<br />
=== Prefix to Infix ===<br />
<br />
The following sequence of steps illustrates converting $(3*4+{8\over{2}})^{(7-5)}$ from its prefix representation to infix:<br />
::{| class="wikitable" style="text-align: left"<br />
|-<br />
! ↑ + * 3 4 / 8 2 – 7 5 <br />
|-<br />
| style="background-color: #ffffff" | ↑ + <syntaxhighlight lang="python" inline>(3*4)</syntaxhighlight> / 8 2 – 7 5<br />
|-<br />
| style="background-color: #ffffff" |↑ + <syntaxhighlight lang="python" inline>(3*4)</syntaxhighlight> <syntaxhighlight lang="python" inline>(8/2)</syntaxhighlight> – 7 5<br />
|-<br />
| style="background-color: #ffffff" |↑ <syntaxhighlight lang="python" inline>(3*4)+(8/2)</syntaxhighlight> - 7 5<br />
|-<br />
| style="background-color: #ffffff" |↑ <syntaxhighlight lang="python" inline>((3*4)+(8/2))</syntaxhighlight> <syntaxhighlight lang="python" inline>(7-5)</syntaxhighlight><br />
|-<br />
| style="background-color: #ffffff" |<syntaxhighlight lang="python" inline>(((3*4)+(8/2))↑(7-5))</syntaxhighlight><br />
|}<br />
<br />
=== Postfix to Infix ===<br />
<br />
The following sequence of steps illustrates converting $(3*4+{8\over{2}})^{(7-5)}$ from its postfix representation to infix:<br />
::{| class="wikitable" style="text-align: left"<br />
|-<br />
!3 4 * 8 2 / + 7 5 -↑<br />
|-<br />
| style="background-color: #ffffff" | <syntaxhighlight lang="python" inline>(3*4)</syntaxhighlight> 8 2 / + 7 5 - ↑<br />
|-<br />
| style="background-color: #ffffff" | <syntaxhighlight lang="python" inline>(3*4)</syntaxhighlight> <syntaxhighlight lang="python" inline>(8/2)</syntaxhighlight> + 7 5 - ↑<br />
|-<br />
| style="background-color: #ffffff" | <syntaxhighlight lang="python" inline>((3*4)+(8/2))</syntaxhighlight> 7 5 -↑ <br />
|-<br />
| style="background-color: #ffffff" | <syntaxhighlight lang="python" inline>((3*4)+(8/2))</syntaxhighlight> <syntaxhighlight lang="python" inline>(7-5)</syntaxhighlight> ↑ <br />
|-<br />
| style="background-color: #ffffff" |<syntaxhighlight lang="python" inline>(((3*4)+(8/2))↑(7-5))</syntaxhighlight> <br />
|}<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some previous problems.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/Lj91oRv3EIY</youtube><br />
| [https://youtu.be/Lj91oRv3EIY ''ACSL Prep - Mrs. Gupta - Prefix Infix Postfix'' ('''MegaChristian5555''')]<br />
<br />
This video starts with a nice introduction to the category, and then solves a handful of practice problems.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/lDm08rP_lms</youtube><br />
| [https://youtu.be/lDm08rP_lms ''ACSL Prefix Postfix Infix Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Mr. Minich is an ACSL advisor. This video was created to help prepare his students for the ACSL Prefix/Infix/Postfix category. It shows solutions to 5 different problems that have<br />
appeared in recent years. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/4YZdsw2UOpo</youtube><br />
| [https://youtu.be/4YZdsw2UOpo ''Prefix Notation'' ('''Tangerine Code''')]<br />
<br />
To quote the video description: ''A general tutorial on prefix notation that can be used for American Computer Science League.''<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/R-t9-rbJDw8</youtube><br />
| [https://youtu.be/R-t9-rbJDw8 ''Postfix Notation'' ('''Tangerine Code''')]<br />
<br />
To quote the video description: ''A general tutorial on postfix notation that can be used for American Computer Science League.''<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/dcc-nXY2L6c</youtube><br />
| [https://youtu.be/dcc-nXY2L6c ''2015 16 Contest 2 Prefix Infix Postfix Problem#1'' ('''Ravi Yeluru''')]<br />
<br />
Ravi Yeluru walks through the solution to an ACSL Prefix/Infix/Postfix program that appeared in the 2015-16 year, Contest #2.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/lEIPvUqstEY</youtube><br />
| [https://youtu.be/lEIPvUqstEY ''2015 16 Contest 2 Prefix Infix Postfix Problem#2'' ('''Ravi Yeluru''')]<br />
<br />
Ravi Yeluru walks through the solution to an ACSL Prefix/Infix/Postfix program that appeared in the 2015-16 year, Contest #2.<br />
<br />
|}<br />
<br />
=== Other Videos ===<br />
<br />
The following YouTube videos cover various aspects of this topic; they were created by authors who are not involved (or aware) of ACSL, to the best of our knowledge. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t7YWDiz8LMY</youtube><br />
| [https://youtu.be/t7YWDiz8LMY ''Infix Postfix and Prefix Notation'' ('''Carleton Moore''')]<br />
<br />
A very gentle overview of infix, prefix, and postfix.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/z3VsmufB_QI</youtube><br />
| [https://youtu.be/z3VsmufB_Q I''Infix Prefix and Postfix'' ('''University Academy''')]<br />
<br />
Another very gentle overview of infix, prefix, and postfix.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jos1Flt21is</youtube><br />
| [https://youtu.be/jos1Flt21is ''Infix Postfix and Prefix Notation'' ('''mycodeschool''')]<br />
<br />
Another overview of infix, prefix, and postfix notations.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/MeRb_1bddWg</youtube><br />
| [https://youtu.be/MeRb_1bddWg ''Evaluation of Prefix and Postfix expressions using stack'' ('''mycodeschool''')]<br />
<br />
Describes the standard algorithm to evaluate prefix and postfix expressions.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/vq-nUF0G4fI</youtube><br />
| [https://youtu.be/vq-nUF0G4fI ''Infix to Postfix using stack'' ('''mycodeschool''')]<br />
<br />
Describes the standard algorithm to convert from infix to postfix. <br />
|}<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Prefix/Infix/Postfix_Notation&diff=568Prefix/Infix/Postfix Notation2018-09-09T09:39:31Z<p>Marc Brown: </p>
<hr />
<div>The expression $5+\large{8\over{3-1}}$ clearly has a value of 9. It is written in ''infix'' notation as $5+8/(3-1)$. The value of an ''infix'' version is well-defined because there is a well-established order of precedence in mathematics: We first evaluate the parentheses (3-1=2); then, because division has higher precedence that subtraction, we next do 8/2=4. And finally, 5+4=9. The order of precedence is often given the mnemonic of '''Please excuse my dear Aunt Sue''', or '''PEMDAS''': '''p'''arentheses, '''e'''xponentiation, '''m'''ultiplication/'''d'''ivision, and '''a'''ddition/''''s'''ubtraction. Multiplication and division have the same level of precedence; addition and subtraction also have the same level of precedence. Terms with equals precedence are evaluated from left-to-right [https://en.wikipedia.org/wiki/Order_of_operations wikipedia].<br />
<br />
The algorithm to evaluate an ''infix'' expression is complex, as it must address the order of precedence. Two alternative notations have been developed which lend themselves to simple computer algorithms for evaluating expressions. In ''prefix'' notation, each operator is placed before its operands . The expression above would be <syntaxhighlight lang="python" inline>+ 5 / 8 - 3 1</syntaxhighlight>. In ''postfix'' notation, each operator is placed after its operand. The expression above is <syntaxhighlight lang="python" inline>5 8 3 1 - / +</syntaxhighlight>. In ''prefix'' and ''postfix'' notations, there is no notion of order of precedence, nor are there any parentheses. The evaluation is the same regardless of the operators. <br />
<br />
Problems in this category ask to convert between prefix, infix, and postfix, or to evaluate an expression in prefix or postfix.<br />
<br />
== Converting Expressions ==<br />
<br />
An algorithm for converting from infix to prefix (postfix) is as follows:<br />
* Fully parenthesize the infix expression. It should now consist solely of “terms”: a binary operator sandwiched between two operands.<br />
* Write down the operands in the same order that they appear in the infix expression.<br />
* Look at each term in the infix expression in the order that one would evaluate them, i.e., inner-most parenthesis to outer-most and left to right among terms of the same depth.<br />
* For each term, write down the operand before (after) the operators. <br />
<br />
One way to convert from prefix (postfix) to infix is to make repeated scans through the expression. <br />
Each scan, find an operator with two adjacent operators and replace it with a parenthesized infix expression. <br />
This is not the most efficient algorithm, but works well for a human.<br />
<br />
A quick check for determining whether a conversion is correct is to convert the result back into the original format. <br />
<br />
== Context ==<br />
<br />
''Prefix'' and ''postfix'' notation is also known as ''Polish'' and ''Reverse Polish'' notation, respectively, for the Polish logician Jan Lukasiewicz. <br />
<br />
== Examples ==<br />
<br />
=== Infix to Prefix ===<br />
<br />
<br />
The following sequence of steps illustrates converting $X=\left(AB-{C\over{D}}\right)^E$ from infix to prefix:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!(X = (((A * B) - (C / D)) ↑ E)) <br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" |X A B C D E <br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>* A B</syntaxhighlight> C D E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>* A B</syntaxhighlight> <syntaxhighlight lang="python" inline>/ C D</syntaxhighlight> E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>- * A B / C D</syntaxhighlight> E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>↑- * A B / C D E</syntaxhighlight><br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | <syntaxhighlight lang="python" inline>= X ↑ - * A B / C D E</syntaxhighlight><br />
|}<br />
<br />
=== Infix to Postfix ===<br />
<br />
<br />
The following sequence of steps illustrates converting $X=\left(AB-{C\over{D}}\right)^E$ from infix to postfix:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!(X = (((A * B) - (C / D)) ↑ E))<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" |X A B C D E <br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>A B *</syntaxhighlight> C D E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>A B *</syntaxhighlight> <syntaxhighlight lang="python" inline>C D /</syntaxhighlight> E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>A B * C D / -</syntaxhighlight> E<br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | X <syntaxhighlight lang="python" inline>A B * C D / - E ↑</syntaxhighlight><br />
|-<br />
| style="background-color: #ffffff; text-align: left; padding-left: 2em" | <syntaxhighlight lang="python" inline> X A B * C D / - E ↑ =</syntaxhighlight><br />
|}<br />
<br />
=== Prefix to Infix ===<br />
<br />
The following sequence of steps illustrates converting $(3*4+{8\over{2}})^{(7-5)}$ from its prefix representation to infix:<br />
::{| class="wikitable" style="text-align: left"<br />
|-<br />
! ↑ + * 3 4 / 8 2 – 7 5 <br />
|-<br />
| style="background-color: #ffffff" | ↑ + <syntaxhighlight lang="python" inline>(3*4)</syntaxhighlight> / 8 2 – 7 5<br />
|-<br />
| style="background-color: #ffffff" |↑ + <syntaxhighlight lang="python" inline>(3*4)</syntaxhighlight> <syntaxhighlight lang="python" inline>(8/2)</syntaxhighlight> – 7 5<br />
|-<br />
| style="background-color: #ffffff" |↑ <syntaxhighlight lang="python" inline>(3*4)+(8/2)</syntaxhighlight> - 7 5<br />
|-<br />
| style="background-color: #ffffff" |↑ <syntaxhighlight lang="python" inline>((3*4)+(8/2))</syntaxhighlight> <syntaxhighlight lang="python" inline>(7-5)</syntaxhighlight><br />
|-<br />
| style="background-color: #ffffff" |<syntaxhighlight lang="python" inline>(((3*4)+(8/2))↑(7-5))</syntaxhighlight><br />
|}<br />
<br />
=== Postfix to Infix ===<br />
<br />
The following sequence of steps illustrates converting $(3*4+{8\over{2}})^{(7-5)}$ from its postfix representation to infix:<br />
::{| class="wikitable" style="text-align: left"<br />
|-<br />
!3 4 * 8 2 / + 7 5 -↑<br />
|-<br />
| style="background-color: #ffffff" | <syntaxhighlight lang="python" inline>(3*4)</syntaxhighlight> 8 2 / + 7 5 - ↑<br />
|-<br />
| style="background-color: #ffffff" | <syntaxhighlight lang="python" inline>(3*4)</syntaxhighlight> <syntaxhighlight lang="python" inline>(8/2)</syntaxhighlight> + 7 5 - ↑<br />
|-<br />
| style="background-color: #ffffff" | <syntaxhighlight lang="python" inline>((3*4)+(8/2))</syntaxhighlight> 7 5 -↑ <br />
|-<br />
| style="background-color: #ffffff" | <syntaxhighlight lang="python" inline>((3*4)+(8/2))</syntaxhighlight> <syntaxhighlight lang="python" inline>(7-5)</syntaxhighlight> ↑ <br />
|-<br />
| style="background-color: #ffffff" |<syntaxhighlight lang="python" inline>(((3*4)+(8/2))↑(7-5))</syntaxhighlight> <br />
|}<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some previous problems.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/Lj91oRv3EIY</youtube><br />
| [https://youtu.be/Lj91oRv3EIY ''ACSL Prep - Mrs. Gupta - Prefix Infix Postfix'' ('''MegaChristian5555''')]<br />
<br />
This video starts with a nice introduction to the category, and then solves a handful of practice problems.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/lDm08rP_lms</youtube><br />
| [https://youtu.be/lDm08rP_lms ''ACSL Prefix Postfix Infix Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Mr. Minich is an ACSL advisor. This video was created to help prepare his students for the ACSL Prefix/Infix/Postfix category. It shows solutions to 5 different problems that have<br />
appeared in recent years. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/4YZdsw2UOpo</youtube><br />
| [https://youtu.be/4YZdsw2UOpo ''Prefix Notation'' ('''Tangerine Code''')]<br />
<br />
To quote the video description: ''A general tutorial on prefix notation that can be used for American Computer Science League.''<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/R-t9-rbJDw8</youtube><br />
| [https://youtu.be/R-t9-rbJDw8 ''Postfix Notation'' ('''Tangerine Code''')]<br />
<br />
To quote the video description: ''A general tutorial on postfix notation that can be used for American Computer Science League.''<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/dcc-nXY2L6c</youtube><br />
| [https://youtu.be/dcc-nXY2L6c ''2015 16 Contest 2 Prefix Infix Postfix Problem#1'' ('''Ravi Yeluru''')]<br />
<br />
Ravi Yeluru walks through the solution to an ACSL Prefix/Infix/Postfix program that appeared in the 2015-16 year, Contest #2.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/lEIPvUqstEY</youtube><br />
| [https://youtu.be/lEIPvUqstEY ''2015 16 Contest 2 Prefix Infix Postfix Problem#2'' ('''Ravi Yeluru''')]<br />
<br />
Ravi Yeluru walks through the solution to an ACSL Prefix/Infix/Postfix program that appeared in the 2015-16 year, Contest #2.<br />
<br />
|}<br />
<br />
=== Other Videos ===<br />
<br />
The following YouTube videos cover various aspects of this topic; they were created by authors who are not involved (or aware) of ACSL, to the best of our knowledge. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t7YWDiz8LMY</youtube><br />
| [https://youtu.be/t7YWDiz8LMY ''Infix Postfix and Prefix Notation'' ('''Carleton Moore''')]<br />
<br />
A very gentle overview of infix, prefix, and postfix.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/z3VsmufB_QI</youtube><br />
| [https://youtu.be/z3VsmufB_Q I''Infix Prefix and Postfix'' ('''University Academy''')]<br />
<br />
Another very gentle overview of infix, prefix, and postfix.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jos1Flt21is</youtube><br />
| [https://youtu.be/jos1Flt21is ''Infix Postfix and Prefix Notation'' ('''mycodeschool''')]<br />
<br />
Another overview of infix, prefix, and postfix notations.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/MeRb_1bddWg</youtube><br />
| [https://youtu.be/MeRb_1bddWg ''Evaluation of Prefix and Postfix expressions using stack'' ('''mycodeschool''')]<br />
<br />
Describes the standard algorithm to evaluate prefix and postfix expressions.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/vq-nUF0G4fI</youtube><br />
| [https://youtu.be/vq-nUF0G4fI ''Infix to Postfix using stack'' ('''mycodeschool''')]<br />
<br />
Describes the standard algorithm to convert from infix to postfix. <br />
|}<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=LISP&diff=567LISP2018-09-09T09:36:41Z<p>Marc Brown: /* Sample Problems */</p>
<hr />
<div>LISP is one of the simplest computer languages in terms of syntax and semantics, and also one of the most powerful. It was developed in the mid-1950’s by John McCarthy at M.I.T. as a “LISt Processing language.” It has been historically used for virtually all Artificial Intelligence programs and is often the environment of choice for applications which require a powerful interactive working environment. LISP presents a very different way to think about programming from the “algorithmic” languages, such as Python, C++, and Java.<br />
<br />
== Syntax ==<br />
<br />
As its name implies, the basis of LISP is a list. One constructs a list by enumerating elements inside a pair of parentheses. For example, here is a list with four elements (the second element is also a list):<br />
<br />
:<code>(23 (this is easy) hello 821)</code><br />
<br />
The elements in the list, which are not lists, are called “atoms.” For example, the atoms in the list above are: 23, ‘this, ‘hello, 821, ‘easy, and ‘is. Literals are identified with a single leading quote. Everything in LISP is either an atom or a list (but not both). The only exception is “NIL,” which is both an atom and a list. It can also be written as “()” – a pair of parentheses with nothing inside.<br />
<br />
All statements in LISP are function calls with the following syntax: (function arg1 arg2 arg3 … argn). To evaluate a LISP statement, each of the arguments (possibly functions themselves) are evaluated, and then the function is invoked with the arguments. For example, (MULT (ADD 2 3) (ADD 1 4 2)) has a value of 35, since (ADD 2 3) has a value of 5, (ADD 1 4 2) has a value of 7, and (MULT 5 7) has a value of 35. Some functions have an arbitrary number of arguments; others require a fixed number. All statements return a value, which is either an atom or a list. <br />
<br />
== Basic Functions (SET, SETQ, EVAL, ATOM) ==<br />
<br />
We may assign values to variables using the function SET. For example, the statement (SET ’test 6) would have a value of a 6, and (more importantly, however) would also cause the atom ‘test to be bound to the atom 6. The function SETQ is the same as SET, but it causes LISP to act as if the first argument was quoted. <br />
Observe the following examples:<br />
<br />
:{| class="wikitable" style="text-align: left"<br />
!Statement || Value || Comment <br />
|-<br />
|(SET ’a ( MULT 2 3))<br />
|6<br />
|a is an atom with a vaue of 6<br />
|-<br />
|(SET ’a ’(MULT 2 3))<br />
|(MULT 2 3)<br />
|a is a list with 3 elements<br />
|-<br />
|(SET ’b ’a)<br />
|a<br />
|b is an atom with a value of the character a<br />
|-<br />
|(SET ’c a)<br />
|(MULT 2 3)<br />
|c is a list with 3 elements<br />
|-<br />
|(SETQ EX (ADD 3 (MULT 2 5)))<br />
|13<br />
|The variable EX has a value of 13<br />
|-<br />
|(SETQ VOWELS ’(A E I O U))<br />
|(A E I O U)<br />
|VOWELS is a list of 5 elements<br />
|}<br />
<br />
The function EVAL returns the value of its argument, after it has been evaluated. For example, (SETQ z ’(ADD 2 3)) has a value of the list (ADD 2 3); the function (EVAL ’z) has a value of (ADD 2 3); the function (EVAL z) has a value of 5 (but the binding of the atom z has not changed). In this last example, you can think of z being “resolved” twice: once because it is an argument to a function and LISP evaluates all arguments to functions before the function is invoked, and once when the function EVAL is invoked to resolve arguments. The function ATOM can be used to determine whether an item is an atom or a list. It returns either "true", or "NIL" for false. Consider the following examples:<br />
<br />
:{| class="wikitable" style="text-align: left"<br />
!Statement || Value || Comment <br />
|-<br />
|(SETQ p '(ADD 1 2 3 4))<br />
|(ADD 1 2 3 4)<br />
|p is a list with 5 elements<br />
|-<br />
|(ATOM 'p)<br />
|true<br />
|The argument to ATOM is the ato p<br />
|-<br />
|(ATOM p)<br />
|NIL<br />
|Because p is not quoted, it is evaluated to the 5-element list.<br />
|-<br />
|(EVAL p)<br />
|10<br />
|The argument to EVAL is the value of p; the value of p is 10. <br />
|}<br />
<br />
== List Functions (CAR, CDR, CONS, REVERSE)==<br />
<br />
The two most famous LISP functions are CAR and CDR (pronounced: could-er), named after registers of a now long-forgotten IBM machine on which LISP was first developed. The function (CAR x) returns the first item of the list x (and x must be a list or an error will occur); (CDR x) returns the list without its first element (again, x must be a list). The function CONS takes two arguments, of which the second must be a list. It returns a list which is composed by placing the first argument as the first element in the second argument’s list. The function REVERSE returns a list which is its arguments in reverse order. <br />
<br />
The CAR and CDR functions are used extensively to grab specific elements of a list or sublist, that there's a shorthand for this: (CADR x) is the same as (CAR (CDR x)), which retrieves the second element of the list x; (CAADDAR x) is a shorthand for (CAR (CAR (CDR (CDR (CAR x))))), and so on.<br />
<br />
The following examples illustrate the use of CAR, CDR, CONS, and REVERSE: <br />
<br />
:{| class="wikitable" style="text-align: left"<br />
!Statement || Value<br />
|-<br />
|(CAR ’(This is a list))<br />
|This<br />
|-<br />
|(CDR ’(This is a list)))<br />
|(is a list)<br />
|-<br />
|(CONS 'red '(white blue))<br />
|(red white blue)<br />
|-<br />
|(SETQ z (CONS '(red white blue) (CDR ’(This is a list)))))<br />
|((red white blue) is a list)<br />
|-<br />
|(REVERSE z)<br />
|(list a is (red white blue))<br />
|-<br />
|(CDDAR z)<br />
|(blue)<br />
|}<br />
<br />
== Arithmetic Functions (ADD, MULT, ...)==<br />
<br />
As you have probably already figured out, the function ADD simply summed its arguments. We’ll also be using the following arithmetic functions:<br />
<br />
:{| class="wikitable" style="text-align: left"<br />
!'''Function''' || '''Result'''<br />
|-<br />
|(ADD x1 x2 …)<br />
|sum of all arguments<br />
|-<br />
|(SUB a b)<br />
|a-b<br />
|-<br />
|(MULT x1 x2 …)<br />
|product of all arguments<br />
|-<br />
|(DIV a b)<br />
|a/b<br />
|-<br />
|(SQUARE a)<br />
|a*a<br />
|-<br />
|(EXP a n)<br />
|a<sup>n</sup><br />
|-<br />
|(EQ a b)<br />
|true if a and b are equal, NIL otherwise<br />
|-<br />
|(POS a)<br />
|true if a is positive, NIL otherwise<br />
|-<br />
|(NEG a)<br />
|true if a is negative, NIL otherwise<br />
|-<br />
|}<br />
<br />
Functions ADD, SUB, MULT, and DIV can be written as their common mathematical symbols, +, -, *, and /. Here are some examples of these functions:<br />
<br />
:{| class="wikitable"<br />
!'''Statement''' || '''Value'''<br />
|-<br />
|(ADD (EXP 2 3) (SUB 4 1) (DIV 54 4))<br />
|24.5<br />
|-<br />
|(- (* 3 2) (- 12 (+ 1 2 1)))<br />
| -2<br />
|-<br />
|(ADD (SQUARE 3) (SQUARE 4))<br />
|25<br />
|}<br />
<br />
== User-defined Functions ==<br />
<br />
LISP also allows us to create our own functions using the DEF function. (We will sometimes use DEFUN rather than DEF, as it is a bit more standard terminology.) For example,<br />
(DEF SECOND (args) (CAR (CDR args)))<br />
defines a new function called SECOND which operates on a single parameter named “args”. SECOND will take the CDR of the parameter and then the CAR of that result. So, for example:<br />
(SECOND ’(a b c d e))<br />
would first CDR the list to give (b c d e), and then CAR that value returning the single character “b”. Consider the following program fragment:<br />
:(SETQ X ’(a c s l))<br />
:(DEF WHAT(args) (CONS args (REVERSE (CDR args))))<br />
:(DEF SECOND(args) (CONS (CAR (CDR args)) NIL))<br />
<br />
The following chart illustrates the use of the user-defined functions WHAT and SECOND:<br />
<br />
:{| class="wikitable"<br />
!Statement || Value<br />
|-<br />
|(WHAT X) || ((a c s l) l s c)<br />
|-<br />
|(SECOND X) || (c)<br />
|-<br />
|(SECOND (WHAT X)) || (l)<br />
|-<br />
|(WHAT (SECOND X)) || ((c))<br />
|}<br />
<br />
== Online Interpreters ==<br />
<br />
There are many online LISP interpreters available on the Internet. The one that ACSL uses for testing its programs is CLISP that is accessible from [https://www.jdoodle.com/execute-clisp-online JDoodle]. This interpreter is nice because it is quite peppy in running programs, and functions are not case sensitive. So, <code>(CAR (CDR x))</code> is legal as is <code>(car (cdr x))</code> One drawback of this interpreter is the print function changes lowercase input into uppercase. <br />
<br />
== Sample Problems ==<br />
<br />
Questions from this topic will typically present a line of LISP code or a short sequence of statements and ask what is the value of the (final) statement.<br />
<br />
=== Problem 1 ===<br />
<br />
Evaluate the following expression. <code>(MULT (ADD 6 5 0) (MULT 5 1 2 2) (DIV 9 (SUB 2 5)))</code><br />
<br />
'''Solution:'''<br />
(MULT (ADD 6 5 0) (MULT 5 1 2 2) (DIV 6 (SUB 2 5)))<br />
(MULT 11 20 (DIV 6 -3))<br />
(MULT 11 20 -2)<br />
-440<br />
<br />
=== Problem 2 ===<br />
<br />
Evaluate the following expression: <code>(CDR ’((2 (3))(4 (5 6) 7)))</code><br />
<br />
'''Solution:'''<br />
The CDR function takes the first element of its parameter (which is assumed to be a list) and returns the list with the first element removed. The first element of the list is (2 (3)) and the list without this element is<br />
((4 (5 6) 7)), a list with one element.<br />
<br />
=== Problem 3 ===<br />
<br />
Consider the following program fragment:<br />
<syntaxhighlight><br />
(SETQ X ’(RI VA FL CA TX))<br />
(CAR (CDR (REVERSE X)))<br />
</syntaxhighlight><br />
What is the value of the CAR expression? <br />
<br />
'''Solution:'''<br />
The first statement binds variable X to the list ‘(RI VA FL CA TX).<br />
The REVERSE of this list is ‘(TX CA FL VA RI)<br />
whose CDR is ‘(CA FL VA RI). The CAR of this list is just the atom CA (without the quote).<br />
<br />
<!-- <br />
<br />
Too scary of a sample problem! --marc 9/3/2018<br />
<br />
=== Problem 4 ===<br />
<br />
Given the function definitions for HY and FY as follows:<br />
(DEFUN HY(PARM) (REVERSE (CDR PARM)))<br />
(DEFUN FY(PARM) (CAR (HY (CDR PARM))))<br />
What is the value of the following?<br />
(FY ’(DO RE (MI FA) SO))<br />
<br />
'''Solution:'''<br />
To evaluate (FY ’(DO RE (MI FA) SO)), we must evaluate<br />
(CAR (HY (CDR ’(DO RE (MI FA) SO)))).<br />
Thus, HY is invoked with <br />
PARM = ’(RE (MI FA) SO), and we evaluate<br />
(REVERSE (CDR ’(RE (MI FA) SO)))<br />
This has a value of (SO (MI FA)) which is returned to FY. FY now takes the CAR of this which is SO (without the quotes).<br />
--><br />
<br />
== Video Resources ==<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jWFgmE279eQ</youtube><br />
| [https://youtu.be/jWFgmE279eQ ''LISP very gentle intro'' ('''CalculusNguyenify''')]<br />
<br />
A very gentle introduction to the LISP category, covering the LISP syntax and the basic operators, SETQ, ADD, SUB, MULT, and DIV.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/mRpbbss48sw</youtube><br />
| [https://youtu.be/mRpbbss48sw ''LISP Basics (for ACSL)'' ('''Tangerine Code''')]<br />
<br />
Explains the LISP operators CAR, CDR, and REVERSE, in the context of solving an ACSL All-Star Contest problem.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/50wj_f51kBM</youtube><br />
| [https://youtu.be/50wj_f51kBM ''LISP Basics (for ACSL)'' ('''Tangerine Code''')]<br />
<br />
Completes the problem that was started in the above video. <br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Bit-String_Flicking&diff=566Bit-String Flicking2018-09-09T09:36:07Z<p>Marc Brown: /* Sample Problems */</p>
<hr />
<div><br />
Bit strings (strings of binary digits) are frequently manipulated bit-by-bit using the logical operators '''not''', '''and''', '''or''', and '''xor'''. Bits strings are manipulated as a unit using '''shift''' and '''circulate''' operators. The bits on the left are called the ''most significant bits'' and those on the right are the ''least significant bits''. <br />
<br />
Most high-level languages (e.g., Python, Java, C++), support bit-string operations. Programmers typically use bit strings to maintain a set of flags. Suppose that a program supports 8 options, each of which can be either “on” or “off”. One could maintain this information using an array of size 8, or one could use a single variable (if it is internally stored using at least 8 bits or 1 byte, which is usually the case) and represent each option with a single bit. In addition to saving space, the program is often cleaner if a single variable is involved rather than an array. Bits strings are often used to maintain a set where values are either in the set or not. Shifting of bits is also used to multiply or divide by powers of 2.<br />
<br />
Mastering this topic is essential for systems programming, programming in assembly language, optimizing code, and hardware design.<br />
<br />
== Operators==<br />
<br />
=== Bitwise Operators ===<br />
<br />
The logical operators are '''not''' (~ or $\neg$), '''and''' (&), '''or''' (|), and '''xor''' ($\oplus$). These operators should be familiar to ACSL students from the [[Boolean Algebra]] and [[Digital Electronics]] categories.<br />
<br />
* '''not''' is a unary operator that performs logical negation on each bit. Bits that are 0 become 1, and those that are 1 become 0. For example: ~101110 has a value of 010001.<br />
<br />
* '''and''' is a binary operator that performs the logical '''and''' of each bit in each of its operands. The '''and''' of two values is 1 only if both values are 1. For example, '''1011011 and 011001''' has a value of '''001001'''. The '''and''' function is often used to isolate the value of a bit in a bit-string or to clear the value of a bit in a bit-string.<br />
<br />
* '''or''' is a binary operator that performs the logical '''or''' of each bit in each of its operands. The '''or''' of two values is 1 only if one or both values are 1. For example, '''1011011 or 011001''' has a value of '''111011'''. The '''or''' function is often use to force the value of a bit in a bit-string to be 1, if it isn't already.<br />
<br />
* '''xor''' is a binary operator that performs the logical '''xor''' of each bit in each of its operands. The '''xor''' of two values is 1 if the values are different and 0 if they are the same. For example, 1011011 xor 011001 = 110010. The '''xor''' function is often used to change the value of a particular bit.<br />
<br />
All binary operators (and, or, or xor) must operate on bit-strings that are of<br />
the same length. If the operands are not the same<br />
length, the shorter one is padded with 0's on the left as needed. For <br />
example, '''11010 and 1110''' would have value of '''11010 and 01110 = 01010'''.<br />
<br />
The following table summarizes the operators:<br />
<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
! '''not''' <math>x</math><br />
!<math>x</math> '''and''' <math>y</math><br />
!<math>x</math> '''or''' <math>y</math><br />
!<math>x</math> '''xor''' <math>y</math><br />
|-<br />
!0<br />
!0<br />
| 1 <br />
| 0 <br />
| 0 <br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
| 0 <br />
| 1 <br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 0 <br />
| 0 <br />
| 1 <br />
| 0 <br />
|-<br />
!1<br />
!1<br />
| 0 <br />
| 1 <br />
| 1 <br />
| 1 <br />
|}<br />
<br />
=== Shift Operators ===<br />
<br />
Logical shifts (LSHIFT-x and RSHIFT-x) “ripple” the bit-string x positions in the indicated direction, either to the left or to the right. Bits shifted out are lost; zeros are shifted in at the other end. <br />
<br />
Circulates (RCIRC-x and LCIRC-x) “ripple” the bit string x positions in the indicated direction. As each bit is shifted out one end, it is shifted in at the other end. The effect of this is that the bits remain in the same order on the other side of the string.<br />
<br />
The size of a bit-string does not change with shifts, or circulates. If any bit strings are initially of different lengths, all shorter ones are padded with zeros in the left bits until all strings are of the same length. <br />
<br />
The following table gives some examples of these operations:<br />
<br />
::{| class="wikitable" style="text-align: right"<br />
|-<br />
!x<br />
!(LSHIFT-2 x)<br />
!(RSHIFT-3 x)<br />
!(LCIRC-3 x)<br />
!(RCIRC-1 x)<br />
|-<br />
!01101<br />
| 10100<br />
| 00001<br />
| 01011<br />
| 10110<br />
|-<br />
!10<br />
| 00<br />
| 00<br />
| 01<br />
| 01<br />
|-<br />
!1110<br />
| 1000<br />
| 0001<br />
| 0111<br />
| 0111<br />
|-<br />
!1011011<br />
| 1101100<br />
| 0001011<br />
| 1011101<br />
| 1101101<br />
|}<br />
<br />
=== Order of Precedence ===<br />
<br />
The order of precedence (from highest to lowest) is: NOT; SHIFT and CIRC; AND; XOR; and finally, OR. In other words, all unary operators are performed on a single operator first. Operators with equal precedence are evaluated left to right; all unary operators bind from right to left.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Evaluate the following expression: <br />
:(0101110 AND NOT 110110 OR (LSHIFT-2 101010))<br />
<br />
'''Solution:'''<br />
The expression evaluates as follows:<br />
:(0101110 AND '''001001''' OR (LSHIFT-2 101010))<br />
:('''001000''' OR (LSHIFT-3 101010))<br />
:(001000 OR '''010000''')<br />
:'''011000'''<br />
<br />
=== Problem 2 ===<br />
<br />
Evaluate the following expression: <br />
:(RSHIFT-1 (LCIRC-4 (RCIRC-2 01101))) <br />
<br />
'''Solution:'''<br />
The expression evaluates as follows, starting at the innermost parentheses:<br />
:(RCIRC-2 01101) => 01011<br />
:(LCIRC-4 01011) => 10101<br />
:(RSHIFT-1 10101) = 01010<br />
<br />
=== Problem 3 ===<br />
<br />
List all possible values of x (5 bits long) that solve the following equation.<br />
:(LSHIFT-1 (10110 XOR (RCIRC-3 x) AND 11011)) = 01100<br />
<br />
'''Solution:'''<br />
Since x is a string 5 bits long, represent it by abcde. (RCIRC-3 x) is cdeab which, when ANDed with 11011 gives cd0ab. This is XORed to 10110 to yield Cd1Ab (the capital letter is the NOT of its lower case).<br />
Now, (LSHIFT-1 Cd1Ab) = d1Ab0 which has a value of 01100, we must have d=0, A=1 (hence a=0), b=0. Thus, the solution must be in the form 00*0*, where * is an “I-don’t-care”. The four possible values of x are: 00000, 00001, 00100 and 00101.<br />
<br />
=== Problem 4 ===<br />
<br />
Evaluate the following expression:<br />
: ((RCIRC-14 (LCIRC-23 01101)) | (LSHIFT-1 10011) & (RSHIFT-2 10111))<br />
<br />
'''Solution:'''<br />
The problem can be rewritten as <br />
: A | B & C<br />
The AND has higher precedence than the OR. <br />
<br />
The evaluation of expression A can be done in a straightforward way: (LCIRC-23 01101) is the same as (LCIRC-3 01101) which has a value of 01011, and (RCIRC-14 01011) is the same as (RCIRC-4 01011) which has a value of 10110. Another strategy is to offset the left and right circulates. So, ((RCIRC-14 (LCIRC-23 01101)) has the same value as (LCIRC-9 01101), which has the same value as (LCIRC-4 01101) which is also 11010.<br />
<br />
Expressions B and C are pretty easy to evaluate:<br />
:B = (LSHIFT-1 10011) = 00110<br />
:C = (RSHIFT-2 10111) = 00101<br />
<br />
The expression becomes<br />
: A | B & C = 10110 | 00110 & 00101 = 10110 | 00100 = 10110<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/IeMsD3harrE</youtube><br />
| [https://youtu.be/IeMsD3harrE ''Bit String Flicking (Intro)'' ('''CalculusNguyenify''')]<br />
<br />
A great two-part tutorial on this ACSL category. Part 1 covers bitwise operations AND, OR, NOT, and XOR. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jbKw8oYJPs4</youtube><br />
| [https://youtu.be/jbKw8oYJPs4 ''Bit String Flicking Shifts and Circs'' ('''CalculusNguyenify''')]<br />
<br />
Part 2 covers logical shifts and circulate operations.<br />
<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/XNBcO25mgCw</youtube><br />
| [https://youtu.be/XNBcO25mgCw ''Bit String Flicking'' ('''Tangerine Code''')]<br />
<br />
Shows the solution to the problem: (RSHIFT-3 (LCIRC-2 (NOT 10110)))<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/8J9AdxU5CW8</youtube><br />
| [https://youtu.be/8J9AdxU5CW8 ''Bit String Flicking by Ravi Yeluru'' ('''hemsra''')]<br />
<br />
Walks through two problems from the Junior Division.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/aa_lQ8gft60</youtube><br />
| [https://youtu.be/aa_lQ8gft60 ''ACSL BitString Flicking Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Solves a handful of problems given in previous years at the Intermediate Division level.<br />
<br />
|}<br />
<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Boolean_Algebra&diff=565Boolean Algebra2018-09-09T09:35:18Z<p>Marc Brown: /* Sample Problem 2: Find Solutions */</p>
<hr />
<div>''Boolean algebra'' is the branch of algebra in which the values of the variables and constants have exactly two values: ''true'' and ''false'', usually denoted 1 and 0 respectively. <br />
<br />
The basic operators in Boolean algebra are ''and'', ''or'', and ''not''. The secondary operators are ''exclusive or'' (often called ''xor'') and ''exclusive nor'' (sometimes called ''equivalence''). They are secondary in the sense that they <br />
can be composed from the basic operators.<br />
*The ''and'' of two values is true only whenever both values are true. It is written as $xy$ or $x \cdot y$. The values of ''and'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
!<math>x y</math><br />
|-<br />
!0<br />
!0<br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 0 <br />
|-<br />
!1<br />
!0<br />
| 0 <br />
|-<br />
!1<br />
!1<br />
| 1 <br />
|} <br />
<br />
* The ''or'' of two values is true whenever either or both values are true. It is written as $x+y$. The values of ''or'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
!<math>x + y</math><br />
|-<br />
!0<br />
!0<br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 1 <br />
|-<br />
!1<br />
!1<br />
| 1 <br />
|} <br />
<br />
* The ''not'' of a value is its opposite; that is, the ''not'' of a true value is false whereas the ''not'' of a false value is true. It is written as $\overline{x}$ or $\neg{x}$. The values of ''not'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>\overline{x}</math><br />
|-<br />
!0<br />
| 1 <br />
|-<br />
!1<br />
| 0 <br />
|} <br />
<br />
* The ''xor'' of two values is true whenever the values are different. It uses the $\oplus$ operator, and can be built from the basic operators: $x \oplus y = x \overline{y} + \overline{x} y$ The values of ''xor'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
!<math>x \oplus y</math><br />
|-<br />
!0<br />
!0<br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 1 <br />
|-<br />
!1<br />
!1<br />
| 0<br />
|} <br />
<br />
*The ''xnor'' of two values is true whenever the values are the same. It is the ''not'' of the ''xor'' function. It uses the $\odot$ operator: $x \odot y = \overline{x \oplus y}$. The ''xnor'' can be built from basic operators: $x \odot y = x y + \overline{x} \overline{y}$ The values of ''xnor'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
!<math>x \odot y</math><br />
|-<br />
!0<br />
!0<br />
| 1 <br />
|-<br />
!0<br />
!1<br />
| 0<br />
|-<br />
!1<br />
!0<br />
| 0<br />
|-<br />
!1<br />
!1<br />
| 1<br />
|} <br />
<br />
Just as algebra has basic rules for simplifying and evaluating expressions, so does Boolean algebra.<br />
<br />
==Why is Boolean Algebra Important for ACSL Students?==<br />
<br />
Boolean algebra is important to programmers, computer scientists, and the general population. <br />
<br />
*For programmers, Boolean expressions are used for conditionals and loops. For example, the following snippet of code sums the even numbers that are not also multiples of 3, stopping when the sum hits 100:<br />
<br />
<dl><br />
<dd><br />
<syntaxhighlight lang="python"><br />
s = 0<br />
x = 1<br />
while (s < 100):<br />
if (x % 2 == 0) and (x % 3 != 0)<br />
then s = s + x<br />
x = x + 1<br />
</syntaxhighlight><br />
Both the conditional statement <br />
<syntaxhighlight lang="python" inline>s < 100</syntaxhighlight><br />
and the Boolean expression with 2 conditional statements <br />
<syntaxhighlight lang="python" inline>(x % 2 == 0) and (x % 3 != 0)</syntaxhighlight><br />
evaluate to ''true'' or ''false''. <br />
</dd><br />
</dl><br />
<br />
*For computer scientists, Boolean algebra is the basis for digital circuits that make up a computer's hardware. The [[Digital Electronics]] category concerns a graphical representation of a circuit. That circuit is typically easiest to understand and evaluate by converting it to its Boolean algebra representation. <br />
<br />
* The general population uses Boolean algebra, probably without knowing that they are doing so, when they enter search terms in Internet search engines. For example, the search expression "jaguar speed -car is the Boolean expression <syntaxhighlight lang="python" inline>"jaguar" and "car" and not "speed"</syntaxhighlight>; it returns pages about the speed of the jaguar animal, not the Jaguar car.<br />
<br />
==Laws==<br />
A '''law''' of Boolean algebra is an identity such as <math>x + (y + z) = (x + y) + z</math><br />
between two Boolean terms, where a '''Boolean term''' is defined as an expression built up from variables, the constants 0 and 1, and operations ''and'', ''or'', ''not'', ''xor'', and ''xnor''. <br />
<br />
Like ordinary algebra, parentheses are used to group terms. When a ''not'' is represented with an overhead horizontal line, there is an implicit grouping of the terms under the line. That is, $x \cdot \overline{y + z}$ is evaluated as is it were written $x \cdot \overline{(y + z)}.$<br />
<br />
===Order of Precedence===<br />
<br />
The order of operator precedence is ''not''; then ''and''; then ''xor'' and ''xnor''; and finally ''or''. Operators with the same level of precedence are evaluated from left-to-right. <br />
<br />
===Fundamental Identities===<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|- <br />
| style="text-align: left" | Commutative Law – The order of application of two separate terms is not important. || $x+y = y+x$ || $x \cdot y = y \cdot x$ <br />
|- <br />
| style="text-align: left" | Associative Law – Regrouping of the terms in an expression doesn't change the value of the expression. ||$(x + y) + z$ = $x + (y + z)$ || $x \cdot (y \cdot z) = (x \cdot y) \cdot z$ <br />
|-<br />
| style="text-align: left" | Idempotent Law – A term that is ''or'''´ed or ''and''´ed with itself is equal to that term. || $ x +x = x $ || $x \cdot x = x$<br />
|-<br />
| style="text-align: left" | Annihilator Law – A term that is ''or'''´ed with 1 is 1; a term ''and''´ed with 0 is 0. || $x + 1 = 1$ || $ x \cdot 0 = 0 $ <br />
|-<br />
| style="text-align: left" | Identity Law – A term ''or''´ed 0 or ''and''´ed with a 1 will always equal that term. || $x + 0 = x$ || $x \cdot 1 = x$<br />
|-<br />
| style="text-align: left" | Complement Law – A term ''or''´ed with its complement equals 1 and a term ''and''´ed with its complement equals 0. || $x + \overline{x} = 1 $ || $x \cdot \overline{x} = 0$<br />
|-<br />
| style="text-align: left" | Absorptive Law – Complex expressions can be reduced to a simpler ones by absorbing like terms. ||colspan=2|<br />
$x+x y = x$<br />
<br />
$ x +\overline{x}y = x + y $<br />
<br />
$x (x+y) = x$<br />
<br />
|-<br />
| style="text-align: left" | Distributive Law – It's OK to multiply or factor-out an expression.||colspan=2|<br />
<br />
$x \cdot (y + z) = xy + xz$<br />
<br />
$(x+y) \cdot (p + q) = xp + xq +yp + yq$<br />
<br />
$(x+y)(x+z)=x + yz $<br />
<br />
|-<br />
| style="text-align: left" | DeMorgan's Law – An ''or'' (''and'') expression that is negated is equal to the ''and'' (''or'') of the negation of each term.|| $\overline{x+y} = \overline{x} \cdot \overline{y}$||$\overline{x \cdot y} = \overline{x} + \overline{y}$<br />
|- <br />
| style="text-align: left" | Double Negation – A term that is inverted twice is equal to the original term.||colspan=2| $\overline{\overline{x}} = x $ <br />
|- <br />
| style="text-align: left" | Relationship between XOR and XNOR|| colspan=2 | $ x\odot y = \overline{x\oplus y} = x \oplus \overline{y} =\overline{x} \oplus {y}$ <br />
|}<br />
<br />
== Sample Problems ==<br />
<br />
Problems in this category are typically of the form "Given a Boolean expression, simplify it as much as possible" or "Given a Boolean expression,<br />
find the values of all possible inputs that make the expression ''true''." Simplify means writing an equivalent expression using the fewest number of operators.<br />
<br />
=== Problem 1: Simplify the Expression ===<br />
<br />
'''Problem:''' Simplify the following expression as much as possible:<br />
$ \overline{ \overline{A(A+B)} + B\overline{A}}$<br />
<br />
'''Solution:'''<br />
<br />
The simplification proceeds as follows:<br />
<br />
:$\overline{ \overline{A(A+B)} + B\overline{A}}$<br />
::{| <br />
<br />
|-<br />
| <math>= \left(\overline{ \overline{A(A+B)}}\right) \cdot \left(\overline{ B\overline{A}}\right)</math> ||<br />
| (DeMorgan's Law)<br />
<br />
|-<br />
| <math>= \left(A(A+B)\right) \cdot \left( \overline{B}+\overline{\overline{A}}\right)</math> ||<br />
| (Double Negation; DeMorgan's Law)<br />
<br />
|-<br />
| <math>= A \cdot \left( \overline{B}+A\right)</math> ||<br />
| (Absorption; Double Negation)<br />
<br />
|-<br />
| <math>=A</math> || <br />
| (Absorption)<br />
| <br />
<br />
|}<br />
<br />
=== Problem 2: Find Solutions ===<br />
<br />
'''Problem:''' Find all orderd pairs $(A,B)$ that make the following expression ''true'':<br />
$ \overline{ \overline{(A+B)} + \overline{A}B }$<br />
<br />
'''Solution:'''<br />
<br />
There are typically two approaches to solving this type of problem. One approach is to simplify the expression as much as possible, until<br />
it's obvious what the solutions are. The other approach is to create a truth table of all possible inputs, with columns for each subexpression.<br />
<br />
The simplification approach is as following:<br />
:$ \overline{\overline{(A+B)} + \overline{A}B}$<br />
::$= \overline{\overline{A+B}} \cdot \overline{\overline{A}B}$ <br />
::$= (A+B) \cdot (\overline{\overline{A}}+\overline{B} ) $ <br />
::$= (A+B) \cdot (A+\overline{B}) $ <br />
::$= AA + A\overline{B} + BA + B\overline{B} $ <br />
::$= A + A(\overline{B} + B) + 0 $ <br />
::$= A + A(1)$ <br />
::$= A + A$ <br />
::$=A$<br />
This means that all inputs are valid whenever $A$ is ''true'': $(1,0)$ and $(1,1)$<br />
<br />
The truth table approach is as following. Each column is the result of a basic operation on two other columns. <br />
:{| class="wikitable" style="text-align: center"<br />
|-<br />
!style="background-color: #cceeff; font-size: x-small" |#1<br />
!style="background-color: #cceeff; font-size: x-small" |#2<br />
!style="background-color: #cceeff; font-size: x-small" |#3 <br />
!style="background-color: #cceeff; font-size: x-small" |#4<br />
!style="background-color: #cceeff; font-size: x-small" |#5<br />
!style="background-color: #cceeff; font-size: x-small" |#6<br />
!style="background-color: #cceeff; font-size: x-small" |#7<br />
!style="background-color: #cceeff; font-size: x-small" |#8<br />
<br />
|-<br />
|style="background-color: #cceeff"|<br />
|style="background-color: #cceeff"|<br />
!style="background-color: #cceeff; font-size: x-small" |OR of Col#1, Col#2<br />
!style="background-color: #cceeff; font-size: x-small" |NOT of Col#3<br />
!style="background-color: #cceeff; font-size: x-small" |NOT of Col#1<br />
!style="background-color: #cceeff; font-size: x-small" |ADD of Col#1, Col#2<br />
!style="background-color: #cceeff; font-size: x-small" |OR of Col#4, Col#6<br />
!style="background-color: #cceeff; font-size: x-small" |NOT of Col#7 <br />
<br />
|-<br />
!<math>A</math><br />
!<math>B</math><br />
!<math>A+B</math><br />
!<math>\overline{A+B}</math><br />
!<math>\overline{A}</math><br />
!<math>\overline{A}B</math><br />
!<math>\overline{A+B} + \overline{A}B</math><br />
!<math>\overline{\overline{A+B} + \overline{A}B}</math><br />
<br />
|-<br />
!0<br />
!0<br />
|0<br />
|1<br />
|1<br />
|0<br />
|1<br />
!0<br />
<br />
|-<br />
!0<br />
!1<br />
<br />
|1<br />
|0<br />
|1<br />
|1<br />
|1<br />
!0<br />
<br />
|-<br />
!1<br />
!0<br />
<br />
|1<br />
|0<br />
|0<br />
|0<br />
|0<br />
!1<br />
<br />
|-<br />
!1<br />
!1<br />
<br />
|1<br />
|0<br />
|0<br />
|0<br />
|0<br />
!1<br />
|}<br />
<br />
The rightmost column is the expression we are solving; it is ''true'' for the 3rd and 4th rows, where the inputs are $(1,0)$ and $(1,1)$.<br />
<br />
== Online Resources ==<br />
<br />
===Websites===<br />
A great online tutorial on Boolean Algebra is part of [https://ryanstutorials.net/boolean-algebra-tutorial/ Ryan's Tutorials].<br />
<br />
===Videos===<br />
The following YouTube videos show ACSL students and advisors working out some previous problems. To access the YouTube page with the video, click on the title of the video in the icon. (You can also play the video directly by clicking on the arrow in the center of the image; however, you'll <br />
probably want to have a larger viewing of the video since it contains writing on a whiteboard.) Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/1cwO-FtybNw</youtube><br />
| [https://youtu.be/1cwO-FtybNw ''ACSL Prep - Mrs. Gupta - Boolean Algebra'' ('''MegaChristian5555''')]<br />
<br />
Christian is a student participating in ACSL. This video shows how to solve a half-dozen or so Boolean Algebra problems that have appeared in ACSL contests in recent years in the Intermediate and Senior divisions.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/HJdhEjpVYsY</youtube><br />
| [https://youtu.be/HJdhEjpVYsY ''ACSL Boolean Algebra Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Mr. Minich is an ACSL advisor. This video was one of two he created to help prepare his students for the ACSL Boolean algebra category. It shows solutions to 5 different problems that have<br />
appeared in recent years. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/4io6xgz8Zwk</youtube><br />
| [https://youtu.be/4io6xgz8Zwk ''ACSL Boolean Algebra Contest 2 Worksheet 2'' ('''misterminich''') ]<br />
<br />
Mr. Minich is an ACSL advisor. This video was one of two he created to help prepare his students for the ACSL Boolean algebra category. It shows solutions to 5 different problems that have<br />
appeared in recent years. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/6vI1mO1XOjQ</youtube><br />
| [https://youtu.be/6vI1mO1XOjQ ''ACSL 3 13-14 #1 - AM'' ('''Gordon Campbell''')]<br />
<br />
This video walks through the solution to finding all ordered triples that make the following<br />
Boolean expression ''true'':<br />
:<math><br />
(AB+\overline{C})(\overline{A}+BC)(A+\overline{B}+C)<br />
</math><br />
This problem appeared in 2013-2014 in the Senior Division, Contest #3.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/KRKTbAZYlLM</youtube><br />
| [https://youtu.be/KRKTbAZYlLM ''ACSL 3 #1 14-15 - AM'' ('''Gordon Campbell''')]<br />
<br />
This video walks through the simplification of the expression:<br />
:<math><br />
\overline{(\overline{A}+B)}(B+C)\overline{(A+\overline{C})}(A\overline{B}+BC)<br />
</math><br />
This problem appeared in 2014-2015 in the Senior Division, Contest #3.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jDnni-zm2g8</youtube><br />
| [https://youtu.be/jDnni-zm2g8 ''A general tutorial on boolean algebra that can be used for American Computer Science League.'' ('''Tangerine Code''')]<br />
<br />
Walks through the simplification of the following Boolean expression:<br />
:<math><br />
\overline{ (\overline{A + \overline{B}})(AB)} +<br />
\overline{ (A+B)(\overline{\overline{A}B})}<br />
</math><br />
<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/aGJALO57X7o</youtube><br />
| [https://youtu.be/aGJALO57X7o ''Boolean Algebra by Ravi Yeluru'' ]<br />
<br />
Walks through solving a handful of ACSL problems.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/-Iagy51n5bQ</youtube><br />
| [https://youtu.be/-Iagy51n5bQ ''Boolean Algebra by Ravi Yeluru'' ]<br />
<br />
Walks through solving 4 ACSL problems.<br />
<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Boolean_Algebra&diff=564Boolean Algebra2018-09-09T09:35:03Z<p>Marc Brown: /* Sample Problem 1: Simplify the Expression */</p>
<hr />
<div>''Boolean algebra'' is the branch of algebra in which the values of the variables and constants have exactly two values: ''true'' and ''false'', usually denoted 1 and 0 respectively. <br />
<br />
The basic operators in Boolean algebra are ''and'', ''or'', and ''not''. The secondary operators are ''exclusive or'' (often called ''xor'') and ''exclusive nor'' (sometimes called ''equivalence''). They are secondary in the sense that they <br />
can be composed from the basic operators.<br />
*The ''and'' of two values is true only whenever both values are true. It is written as $xy$ or $x \cdot y$. The values of ''and'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
!<math>x y</math><br />
|-<br />
!0<br />
!0<br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 0 <br />
|-<br />
!1<br />
!0<br />
| 0 <br />
|-<br />
!1<br />
!1<br />
| 1 <br />
|} <br />
<br />
* The ''or'' of two values is true whenever either or both values are true. It is written as $x+y$. The values of ''or'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
!<math>x + y</math><br />
|-<br />
!0<br />
!0<br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 1 <br />
|-<br />
!1<br />
!1<br />
| 1 <br />
|} <br />
<br />
* The ''not'' of a value is its opposite; that is, the ''not'' of a true value is false whereas the ''not'' of a false value is true. It is written as $\overline{x}$ or $\neg{x}$. The values of ''not'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>\overline{x}</math><br />
|-<br />
!0<br />
| 1 <br />
|-<br />
!1<br />
| 0 <br />
|} <br />
<br />
* The ''xor'' of two values is true whenever the values are different. It uses the $\oplus$ operator, and can be built from the basic operators: $x \oplus y = x \overline{y} + \overline{x} y$ The values of ''xor'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
!<math>x \oplus y</math><br />
|-<br />
!0<br />
!0<br />
| 0 <br />
|-<br />
!0<br />
!1<br />
| 1 <br />
|-<br />
!1<br />
!0<br />
| 1 <br />
|-<br />
!1<br />
!1<br />
| 0<br />
|} <br />
<br />
*The ''xnor'' of two values is true whenever the values are the same. It is the ''not'' of the ''xor'' function. It uses the $\odot$ operator: $x \odot y = \overline{x \oplus y}$. The ''xnor'' can be built from basic operators: $x \odot y = x y + \overline{x} \overline{y}$ The values of ''xnor'' for all possible inputs is shown in the following truth table:<br />
::{| class="wikitable" style="text-align: center"<br />
|-<br />
!<math>x</math><br />
!<math>y</math><br />
!<math>x \odot y</math><br />
|-<br />
!0<br />
!0<br />
| 1 <br />
|-<br />
!0<br />
!1<br />
| 0<br />
|-<br />
!1<br />
!0<br />
| 0<br />
|-<br />
!1<br />
!1<br />
| 1<br />
|} <br />
<br />
Just as algebra has basic rules for simplifying and evaluating expressions, so does Boolean algebra.<br />
<br />
==Why is Boolean Algebra Important for ACSL Students?==<br />
<br />
Boolean algebra is important to programmers, computer scientists, and the general population. <br />
<br />
*For programmers, Boolean expressions are used for conditionals and loops. For example, the following snippet of code sums the even numbers that are not also multiples of 3, stopping when the sum hits 100:<br />
<br />
<dl><br />
<dd><br />
<syntaxhighlight lang="python"><br />
s = 0<br />
x = 1<br />
while (s < 100):<br />
if (x % 2 == 0) and (x % 3 != 0)<br />
then s = s + x<br />
x = x + 1<br />
</syntaxhighlight><br />
Both the conditional statement <br />
<syntaxhighlight lang="python" inline>s < 100</syntaxhighlight><br />
and the Boolean expression with 2 conditional statements <br />
<syntaxhighlight lang="python" inline>(x % 2 == 0) and (x % 3 != 0)</syntaxhighlight><br />
evaluate to ''true'' or ''false''. <br />
</dd><br />
</dl><br />
<br />
*For computer scientists, Boolean algebra is the basis for digital circuits that make up a computer's hardware. The [[Digital Electronics]] category concerns a graphical representation of a circuit. That circuit is typically easiest to understand and evaluate by converting it to its Boolean algebra representation. <br />
<br />
* The general population uses Boolean algebra, probably without knowing that they are doing so, when they enter search terms in Internet search engines. For example, the search expression "jaguar speed -car is the Boolean expression <syntaxhighlight lang="python" inline>"jaguar" and "car" and not "speed"</syntaxhighlight>; it returns pages about the speed of the jaguar animal, not the Jaguar car.<br />
<br />
==Laws==<br />
A '''law''' of Boolean algebra is an identity such as <math>x + (y + z) = (x + y) + z</math><br />
between two Boolean terms, where a '''Boolean term''' is defined as an expression built up from variables, the constants 0 and 1, and operations ''and'', ''or'', ''not'', ''xor'', and ''xnor''. <br />
<br />
Like ordinary algebra, parentheses are used to group terms. When a ''not'' is represented with an overhead horizontal line, there is an implicit grouping of the terms under the line. That is, $x \cdot \overline{y + z}$ is evaluated as is it were written $x \cdot \overline{(y + z)}.$<br />
<br />
===Order of Precedence===<br />
<br />
The order of operator precedence is ''not''; then ''and''; then ''xor'' and ''xnor''; and finally ''or''. Operators with the same level of precedence are evaluated from left-to-right. <br />
<br />
===Fundamental Identities===<br />
<br />
{| class="wikitable" style="text-align: center"<br />
|- <br />
| style="text-align: left" | Commutative Law – The order of application of two separate terms is not important. || $x+y = y+x$ || $x \cdot y = y \cdot x$ <br />
|- <br />
| style="text-align: left" | Associative Law – Regrouping of the terms in an expression doesn't change the value of the expression. ||$(x + y) + z$ = $x + (y + z)$ || $x \cdot (y \cdot z) = (x \cdot y) \cdot z$ <br />
|-<br />
| style="text-align: left" | Idempotent Law – A term that is ''or'''´ed or ''and''´ed with itself is equal to that term. || $ x +x = x $ || $x \cdot x = x$<br />
|-<br />
| style="text-align: left" | Annihilator Law – A term that is ''or'''´ed with 1 is 1; a term ''and''´ed with 0 is 0. || $x + 1 = 1$ || $ x \cdot 0 = 0 $ <br />
|-<br />
| style="text-align: left" | Identity Law – A term ''or''´ed 0 or ''and''´ed with a 1 will always equal that term. || $x + 0 = x$ || $x \cdot 1 = x$<br />
|-<br />
| style="text-align: left" | Complement Law – A term ''or''´ed with its complement equals 1 and a term ''and''´ed with its complement equals 0. || $x + \overline{x} = 1 $ || $x \cdot \overline{x} = 0$<br />
|-<br />
| style="text-align: left" | Absorptive Law – Complex expressions can be reduced to a simpler ones by absorbing like terms. ||colspan=2|<br />
$x+x y = x$<br />
<br />
$ x +\overline{x}y = x + y $<br />
<br />
$x (x+y) = x$<br />
<br />
|-<br />
| style="text-align: left" | Distributive Law – It's OK to multiply or factor-out an expression.||colspan=2|<br />
<br />
$x \cdot (y + z) = xy + xz$<br />
<br />
$(x+y) \cdot (p + q) = xp + xq +yp + yq$<br />
<br />
$(x+y)(x+z)=x + yz $<br />
<br />
|-<br />
| style="text-align: left" | DeMorgan's Law – An ''or'' (''and'') expression that is negated is equal to the ''and'' (''or'') of the negation of each term.|| $\overline{x+y} = \overline{x} \cdot \overline{y}$||$\overline{x \cdot y} = \overline{x} + \overline{y}$<br />
|- <br />
| style="text-align: left" | Double Negation – A term that is inverted twice is equal to the original term.||colspan=2| $\overline{\overline{x}} = x $ <br />
|- <br />
| style="text-align: left" | Relationship between XOR and XNOR|| colspan=2 | $ x\odot y = \overline{x\oplus y} = x \oplus \overline{y} =\overline{x} \oplus {y}$ <br />
|}<br />
<br />
== Sample Problems ==<br />
<br />
Problems in this category are typically of the form "Given a Boolean expression, simplify it as much as possible" or "Given a Boolean expression,<br />
find the values of all possible inputs that make the expression ''true''." Simplify means writing an equivalent expression using the fewest number of operators.<br />
<br />
=== Problem 1: Simplify the Expression ===<br />
<br />
'''Problem:''' Simplify the following expression as much as possible:<br />
$ \overline{ \overline{A(A+B)} + B\overline{A}}$<br />
<br />
'''Solution:'''<br />
<br />
The simplification proceeds as follows:<br />
<br />
:$\overline{ \overline{A(A+B)} + B\overline{A}}$<br />
::{| <br />
<br />
|-<br />
| <math>= \left(\overline{ \overline{A(A+B)}}\right) \cdot \left(\overline{ B\overline{A}}\right)</math> ||<br />
| (DeMorgan's Law)<br />
<br />
|-<br />
| <math>= \left(A(A+B)\right) \cdot \left( \overline{B}+\overline{\overline{A}}\right)</math> ||<br />
| (Double Negation; DeMorgan's Law)<br />
<br />
|-<br />
| <math>= A \cdot \left( \overline{B}+A\right)</math> ||<br />
| (Absorption; Double Negation)<br />
<br />
|-<br />
| <math>=A</math> || <br />
| (Absorption)<br />
| <br />
<br />
|}<br />
<br />
=== Sample Problem 2: Find Solutions ===<br />
<br />
'''Problem:''' Find all orderd pairs $(A,B)$ that make the following expression ''true'':<br />
$ \overline{ \overline{(A+B)} + \overline{A}B }$<br />
<br />
'''Solution:'''<br />
<br />
There are typically two approaches to solving this type of problem. One approach is to simplify the expression as much as possible, until<br />
it's obvious what the solutions are. The other approach is to create a truth table of all possible inputs, with columns for each subexpression.<br />
<br />
The simplification approach is as following:<br />
:$ \overline{\overline{(A+B)} + \overline{A}B}$<br />
::$= \overline{\overline{A+B}} \cdot \overline{\overline{A}B}$ <br />
::$= (A+B) \cdot (\overline{\overline{A}}+\overline{B} ) $ <br />
::$= (A+B) \cdot (A+\overline{B}) $ <br />
::$= AA + A\overline{B} + BA + B\overline{B} $ <br />
::$= A + A(\overline{B} + B) + 0 $ <br />
::$= A + A(1)$ <br />
::$= A + A$ <br />
::$=A$<br />
This means that all inputs are valid whenever $A$ is ''true'': $(1,0)$ and $(1,1)$<br />
<br />
The truth table approach is as following. Each column is the result of a basic operation on two other columns. <br />
:{| class="wikitable" style="text-align: center"<br />
|-<br />
!style="background-color: #cceeff; font-size: x-small" |#1<br />
!style="background-color: #cceeff; font-size: x-small" |#2<br />
!style="background-color: #cceeff; font-size: x-small" |#3 <br />
!style="background-color: #cceeff; font-size: x-small" |#4<br />
!style="background-color: #cceeff; font-size: x-small" |#5<br />
!style="background-color: #cceeff; font-size: x-small" |#6<br />
!style="background-color: #cceeff; font-size: x-small" |#7<br />
!style="background-color: #cceeff; font-size: x-small" |#8<br />
<br />
|-<br />
|style="background-color: #cceeff"|<br />
|style="background-color: #cceeff"|<br />
!style="background-color: #cceeff; font-size: x-small" |OR of Col#1, Col#2<br />
!style="background-color: #cceeff; font-size: x-small" |NOT of Col#3<br />
!style="background-color: #cceeff; font-size: x-small" |NOT of Col#1<br />
!style="background-color: #cceeff; font-size: x-small" |ADD of Col#1, Col#2<br />
!style="background-color: #cceeff; font-size: x-small" |OR of Col#4, Col#6<br />
!style="background-color: #cceeff; font-size: x-small" |NOT of Col#7 <br />
<br />
|-<br />
!<math>A</math><br />
!<math>B</math><br />
!<math>A+B</math><br />
!<math>\overline{A+B}</math><br />
!<math>\overline{A}</math><br />
!<math>\overline{A}B</math><br />
!<math>\overline{A+B} + \overline{A}B</math><br />
!<math>\overline{\overline{A+B} + \overline{A}B}</math><br />
<br />
|-<br />
!0<br />
!0<br />
|0<br />
|1<br />
|1<br />
|0<br />
|1<br />
!0<br />
<br />
|-<br />
!0<br />
!1<br />
<br />
|1<br />
|0<br />
|1<br />
|1<br />
|1<br />
!0<br />
<br />
|-<br />
!1<br />
!0<br />
<br />
|1<br />
|0<br />
|0<br />
|0<br />
|0<br />
!1<br />
<br />
|-<br />
!1<br />
!1<br />
<br />
|1<br />
|0<br />
|0<br />
|0<br />
|0<br />
!1<br />
|}<br />
<br />
The rightmost column is the expression we are solving; it is ''true'' for the 3rd and 4th rows, where the inputs are $(1,0)$ and $(1,1)$.<br />
<br />
== Online Resources ==<br />
<br />
===Websites===<br />
A great online tutorial on Boolean Algebra is part of [https://ryanstutorials.net/boolean-algebra-tutorial/ Ryan's Tutorials].<br />
<br />
===Videos===<br />
The following YouTube videos show ACSL students and advisors working out some previous problems. To access the YouTube page with the video, click on the title of the video in the icon. (You can also play the video directly by clicking on the arrow in the center of the image; however, you'll <br />
probably want to have a larger viewing of the video since it contains writing on a whiteboard.) Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/1cwO-FtybNw</youtube><br />
| [https://youtu.be/1cwO-FtybNw ''ACSL Prep - Mrs. Gupta - Boolean Algebra'' ('''MegaChristian5555''')]<br />
<br />
Christian is a student participating in ACSL. This video shows how to solve a half-dozen or so Boolean Algebra problems that have appeared in ACSL contests in recent years in the Intermediate and Senior divisions.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/HJdhEjpVYsY</youtube><br />
| [https://youtu.be/HJdhEjpVYsY ''ACSL Boolean Algebra Contest 2 Worksheet 1'' ('''misterminich''')]<br />
<br />
Mr. Minich is an ACSL advisor. This video was one of two he created to help prepare his students for the ACSL Boolean algebra category. It shows solutions to 5 different problems that have<br />
appeared in recent years. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/4io6xgz8Zwk</youtube><br />
| [https://youtu.be/4io6xgz8Zwk ''ACSL Boolean Algebra Contest 2 Worksheet 2'' ('''misterminich''') ]<br />
<br />
Mr. Minich is an ACSL advisor. This video was one of two he created to help prepare his students for the ACSL Boolean algebra category. It shows solutions to 5 different problems that have<br />
appeared in recent years. <br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/6vI1mO1XOjQ</youtube><br />
| [https://youtu.be/6vI1mO1XOjQ ''ACSL 3 13-14 #1 - AM'' ('''Gordon Campbell''')]<br />
<br />
This video walks through the solution to finding all ordered triples that make the following<br />
Boolean expression ''true'':<br />
:<math><br />
(AB+\overline{C})(\overline{A}+BC)(A+\overline{B}+C)<br />
</math><br />
This problem appeared in 2013-2014 in the Senior Division, Contest #3.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/KRKTbAZYlLM</youtube><br />
| [https://youtu.be/KRKTbAZYlLM ''ACSL 3 #1 14-15 - AM'' ('''Gordon Campbell''')]<br />
<br />
This video walks through the simplification of the expression:<br />
:<math><br />
\overline{(\overline{A}+B)}(B+C)\overline{(A+\overline{C})}(A\overline{B}+BC)<br />
</math><br />
This problem appeared in 2014-2015 in the Senior Division, Contest #3.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/jDnni-zm2g8</youtube><br />
| [https://youtu.be/jDnni-zm2g8 ''A general tutorial on boolean algebra that can be used for American Computer Science League.'' ('''Tangerine Code''')]<br />
<br />
Walks through the simplification of the following Boolean expression:<br />
:<math><br />
\overline{ (\overline{A + \overline{B}})(AB)} +<br />
\overline{ (A+B)(\overline{\overline{A}B})}<br />
</math><br />
<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/aGJALO57X7o</youtube><br />
| [https://youtu.be/aGJALO57X7o ''Boolean Algebra by Ravi Yeluru'' ]<br />
<br />
Walks through solving a handful of ACSL problems.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/-Iagy51n5bQ</youtube><br />
| [https://youtu.be/-Iagy51n5bQ ''Boolean Algebra by Ravi Yeluru'' ]<br />
<br />
Walks through solving 4 ACSL problems.<br />
<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Assembly_Language_Programming&diff=563Assembly Language Programming2018-09-09T09:34:33Z<p>Marc Brown: /* Sample Problems */</p>
<hr />
<div>Programs written in high-level languages are traditionally converted by compilers into assembly language, which is turned into machine language programs – sequences of 1’s and 0’s – by an assembler. Even today, with very good quality compilers available, there is the need for programmers to understand assembly language. First, it provides programmers with a better understanding of the compiler and its constraints. Second, on occasion, programmers find themselves needing to program directly in assembly language in order to meet constraints in execution speed or space. <br />
<br />
ACSL chose to define its own assembly language rather than use a “real” one in order to eliminate the many sticky details associated with real languages. The basic concepts of our ACSL topic description are common to all assembly languages. <br />
<br />
== Reference Manual ==<br />
<br />
Execution starts at the first line of the program and continues sequentially, except for branch instructions (BG, BE, BL, BU), until the end instruction (END) is encountered. The result of each operation is stored in a special word of memory, called the “accumulator” (ACC). Each line of an assembly language program has the following fields (lower-case indicates optional components):<br />
<br />
label OPCODE LOC comments<br />
<br />
The ''label'' is a character string beginning in the first column. Valid OPCODE’s are listed in the chart below. The LOC field is either a reference to a label or ''immediate data''. For example, “LOAD A” would put the contents referenced by the label “A” into the ACC; “LOAD =123” would store the value 123 in the ACC. Only those instructions that do not modify the LOC field can use the “immediate data” format. In the following chart, they are indicated by an asterisk in the first column.<br />
<br />
{| class="wikitable" style="text-align: left"|<br />
|-<br />
!OP CODE<br />
!DESCRIPTION<br />
<br />
|-<br />
!*LOAD<br />
|The contents of LOC are placed in the ACC. LOC is unchanged.<br />
<br />
|-<br />
!STORE<br />
|The contents of LOC are placed in the LOC. ACC is unchanged.<br />
<br />
|-<br />
!*ADD<br />
|The contents of LOC are added to the contents of the ACC. The sum is stored in the ACC. LOC is unchanged. Addition is modulo 1,000,000.<br />
<br />
|-<br />
!*SUB<br />
|The contents of LOC are subtracted from the contents of the ACC. The difference is stored in the ACC. LOC is unchanged. Subtraction is modulo 1,000,000.<br />
<br />
|-<br />
!*MULT<br />
|The contents of LOC are multiplied by the contents of the ACC. The product is stored in the ACC. LOC is unchanged. Multiplication is modulo 1,000,000.<br />
<br />
|-<br />
!*DIV<br />
|The contents of LOC are divided into the contents of the ACC. The signed integer part of the quotient is stored in the ACC. LOC is unchanged.<br />
.<br />
|-<br />
!BG<br />
|<br />
Branch to the instruction labeled with LOC if ACC>0.<br />
<br />
|-<br />
!BE<br />
|<br />
Branch to the instruction labeled with LOC if ACC=0.<br />
<br />
|-<br />
!BL<br />
|<br />
Branch to the instruction labeled with LOC if ACC<0.<br />
<br />
|-<br />
!BU<br />
|Branch to the instruction labeled with LOC.<br />
<br />
|-<br />
!READ<br />
|<br />
Read a signed integer (modulo 1,000,000) into LOC.<br />
<br />
|-<br />
!PRINT<br />
|<br />
Print the contents of LOC.<br />
<br />
|-<br />
!DC<br />
|<br />
The value of the memory word defined by the LABEL field is defined to contain the specified constant. The LABEL field is mandatory for this opcode. The ACC is not modified.<br />
<br />
|-<br />
!END<br />
| <br />
Program terminates. LOC field is ignored.<br />
|}<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
After the following program is executed, <br />
what value is in location TEMP?<br />
<br />
{|class="wikitable" style="text-align: left"<br />
|TEMP || DC || 0<br />
|-<br />
|A||DC||8<br />
|-<br />
|B||DC||-2<br />
|-<br />
|C||DC||3<br />
|-<br />
| ||LOAD||B<br />
|-<br />
| ||MULT||C<br />
|-<br />
| ||ADD||A<br />
|-<br />
| ||DIV||B<br />
|-<br />
| ||SUB||A<br />
|-<br />
| ||STORE||TEMP<br />
|-<br />
| ||END||<br />
|}<br />
<br />
'''Solution:''' The ACC takes on values -2, -6, 2, -1, and -9 in that order. The last value, -9, is stored in location TEMP.<br />
<br />
=== Problem 2 ===<br />
<br />
If the following program has an input value<br />
of N, what is the final value of X which is<br />
computed? Express X as an algebraic<br />
expression in terms of N. <br />
<br />
{|class="wikitable" style="text-align: left"<br />
| || READ || X<br />
|-<br />
| || LOAD || X<br />
|-<br />
|TOP || SUB || =1<br />
|-<br />
| || BE || DONE<br />
|-<br />
| || STORE || A<br />
|-<br />
| || MULT || X<br />
|-<br />
| || STORE || X<br />
|-<br />
| || LOAD || A<br />
|-<br />
| || BU || TOP<br />
|-<br />
|DONE || END || <br />
|}<br />
<br />
'''Solution:''' This program loops between labels TOP and<br />
DONE for A times. A has an initial value of X and subsequent terms of N,<br />
then values of A-1, A-2, …, 1. Each time through the loop,<br />
X is multiplied by the the current value of A.<br />
Thus, X = A * (A-1) * (A-2) * … * 1 or X=A! or A factorial.<br />
For example, 5! = 5 * 4 * 3 * 2 * 1 = 120. Since the<br />
initial value of A is the number input (i.e. N),<br />
the algebraic expression is X = N!.<br />
<br />
== Video Resources ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/RUm3iHsbO3I</youtube><br />
| [https://youtu.be/RUm3iHsbO3I ''Intro to Assembly Language'' ('''CalculusNguyenify''')]<br />
<br />
A general introduction into assembly language. In particular, it covers how it fits into the source code to an executable image pipeline.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/i_JYT398O64</youtube><br />
| [https://youtu.be/i_JYT398O64 ''Syntax of ACSL Assembly Language'' ('''CalculusNguyenify''')]<br />
<br />
A very nice introduction to this ACSL category.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/NEQASUsZ0g4</youtube><br />
| [https://youtu.be/NEQASUsZ0g4 ''Examples'' ('''CalculusNguyenify''')]<br />
<br />
Walks through a couple of ACSL Assembly language programs that have been used in previous contests.<br />
<br />
|}<br />
<br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Main_Page&diff=562Main Page2018-09-09T09:24:59Z<p>Marc Brown: </p>
<hr />
<div>Welcome to the wiki describing the topics covered in the short programs section of the [http://www.acsl.org ACSL] contests.<br />
<br />
If you'd like to contribute to this wiki - and we'd love to improve it - please shoot us an email requesting an account. Conversely, if we've linked to your material (especially YouTube videos) that you'd prefer that we do not reference, let us know and we will promptly remove those links.<br />
<br />
Categories covered:<br />
<br />
* [[Assembly Language Programming]] <br />
* [[Bit-String Flicking]] <br />
* [[Boolean Algebra]]<br />
* [[Computer Number Systems]]<br />
* [[Data Structures]]<br />
* [[Digital Electronics]] <br />
* [[Graph Theory]]<br />
* [[LISP]] <br />
* [[Prefix/Infix/Postfix Notation]]<br />
* [[Recursive Functions]]<br />
* [[Regular Expressions]] (in progress)<br />
* [[What Does This Program Do?]]<br />
* [http://www.acsl.org/categories/C1Elem-ComputerNumberSystems.pdf Elementary Division: Computer Number Systems (Contest 1)]<br />
* [http://www.acsl.org/categories/C2Elem-Prefix-Postfix-InfixNotation.pdf Elementary Division: Prefix-Postfix-Infix Notation (Contest 2)]]<br />
* [http://www.acsl.org/categories/C3Elem-BooleanAlgebra.pdf Elementary Division: Boolean Algebra (Contest 3)]<br />
* [http://www.acsl.org/categories/C4Elem-GraphTheory.pdf Elementary Division: Graph Theory (Contest 4)]<br />
<br />
== Getting started ==<br />
* [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software<br />
* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]<br />
* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=561Data Structures2018-09-09T09:24:39Z<p>Marc Brown: /* Problem 3 */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing a set of items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is part of the set and if not, which item in the set is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the set.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire course devoted to fundamental data structures. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form “PUSH(A)” puts the key A at the top of the stack; the command “POP(X)” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH(A)<br />
PUSH(M)<br />
PUSH(E)<br />
POP(X)<br />
PUSH(R)<br />
POP(X)<br />
PUSH(I)<br />
POP(X)<br />
POP(X)<br />
POP(X)<br />
POP(X)<br />
PUSH(C)<br />
PUSH(A)<br />
PUSH(N)<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up".<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
[[File:bst-american.svg|200px]]<br />
<br />
The ''root'' of the resulting tree is the node containing the key A; note that duplicate keys are inserted into the tree as if they were less than their equal key. This is the ACSL convention; in some textbooks and software libraries, duplicate keys may be considered larger than their equal key. The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. An ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, a external node is synonymous with a leaf node. ) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
Binary search trees can support the operations insert, delete, and search. Moreover, it handles the operations efficiently; in a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1000000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, binary search trees can become unbalanced, if the keys being inserted are not pretty random. For example, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y. Sophisticated techniques are available to maintain balanced trees. Binary search trees are “dynamic” data structures that can support an unlimited number of operations in any order. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x<p’s key)<br />
p = p’s left child<br />
else if (x>p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve for the smallest. These insert and delete operations can be done in a guaranteed time proportional to the log of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is smaller than its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right. <br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the child in order to insure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, ''max-heaps'' are also possible and are common in practice. An efficient implementation of a heap uses an array, rather than a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. What is the value of Z when these operations are performed:<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
POP(Y)<br />
POP(X)<br />
PUSH(X-Y)<br />
POP(Z) <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP(Y) stores 8 in Y. The POP(X) stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, POP(Z) removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
[[File:heap-programming.svg|200px]]<br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAM. What is the internal path length? <br />
<br />
Solution: When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, and A and M have a depth of 3. Therefore, the internal path length is 12. Here is the tree:<br />
<br />
[[File:bst-program.svg|200px]]<br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial''with Gayle Laakmann McDowell. The first half of the video is an clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is an clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=File:Bst-program.svg&diff=560File:Bst-program.svg2018-09-09T09:24:18Z<p>Marc Brown: </p>
<hr />
<div></div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=559Data Structures2018-09-09T09:13:16Z<p>Marc Brown: /* Other Videos */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing a set of items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is part of the set and if not, which item in the set is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the set.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire course devoted to fundamental data structures. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form “PUSH(A)” puts the key A at the top of the stack; the command “POP(X)” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH(A)<br />
PUSH(M)<br />
PUSH(E)<br />
POP(X)<br />
PUSH(R)<br />
POP(X)<br />
PUSH(I)<br />
POP(X)<br />
POP(X)<br />
POP(X)<br />
POP(X)<br />
PUSH(C)<br />
PUSH(A)<br />
PUSH(N)<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up".<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
[[File:bst-american.svg|200px]]<br />
<br />
The ''root'' of the resulting tree is the node containing the key A; note that duplicate keys are inserted into the tree as if they were less than their equal key. This is the ACSL convention; in some textbooks and software libraries, duplicate keys may be considered larger than their equal key. The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. An ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, a external node is synonymous with a leaf node. ) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
Binary search trees can support the operations insert, delete, and search. Moreover, it handles the operations efficiently; in a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1000000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, binary search trees can become unbalanced, if the keys being inserted are not pretty random. For example, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y. Sophisticated techniques are available to maintain balanced trees. Binary search trees are “dynamic” data structures that can support an unlimited number of operations in any order. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x<p’s key)<br />
p = p’s left child<br />
else if (x>p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve for the smallest. These insert and delete operations can be done in a guaranteed time proportional to the log of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is smaller than its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right. <br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the child in order to insure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, ''max-heaps'' are also possible and are common in practice. An efficient implementation of a heap uses an array, rather than a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. What is the value of Z when these operations are performed:<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
POP(Y)<br />
POP(X)<br />
PUSH(X-Y)<br />
POP(Z) <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP(Y) stores 8 in Y. The POP(X) stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, POP(Z) removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
[[File:heap-programming.svg|200px]]<br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAMMING. What is the internal path length? <br />
<br />
Solution: When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, A and M have a depth of 3, M and N have a depth of 4, I has a depth of 5, and G has a depth of 6. Therefore, the internal path length is 31.<br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial''with Gayle Laakmann McDowell. The first half of the video is an clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is an clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}<br />
<br />
Here are a few more videos covering the basics of binary search trees.<br />
<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/FvdPo8PBQtc</youtube><br />
| [https://youtu.be/FvdPo8PBQtc ''How to Construct a Binary Search Tree'' ('''edutechional''')]<br />
<br />
''In this algorithm tutorial, I walk through how to construct a binary search tree given an unordered array, and then how to find elements inside of the tree.''<br />
|}</div>Marc Brownhttp://www.categories.acsl.org/wiki/index.php?title=Data_Structures&diff=558Data Structures2018-09-09T09:03:24Z<p>Marc Brown: /* Problem 2 */</p>
<hr />
<div>At the heart of virtually every computer program are its algorithms and its data structures. It is hard to separate these two items, for data structures are meaningless without algorithms to create and manipulate them, and algorithms are usually trivial unless there are data structures on which to operate. The bigger the data sets, the more important data structures are in various algorithms.<br />
<br />
This category concentrates on four of the most basic structures: '''stacks''', '''queues''', '''binary search trees''', and '''priority queues'''. Questions will cover these data structures and implicit algorithms, not specific to implementation language details.<br />
<br />
A ''stack'' is usually used to save information that will need to be processed later. Items are processed in a “last-in, first-out” (LIFO) order. A ''queue'' is usually used to process items in the order in which requests are generated; a new item is not processed until all items currently on the queue are processed. This is also known as “first-in, first-out” (FIFO) order. A ''binary search tree'' is used when one is storing a set of items and needs to be able to efficiently process the operations of insertion, deletion, and query (i.e. find out if a particular item is part of the set and if not, which item in the set is close to the item in question). A ''priority queue'' is used like a binary search tree, except one cannot delete an arbitrary item, nor can one make an arbitrary query. One can only find out or delete the smallest element of the set.<br />
<br />
There are many online resources covering these basic data structures; indeed there are many books and entire course devoted to fundamental data structures. The rest of this page is an overview of these structures.<br />
<br />
== Stacks and Queues ==<br />
<br />
A ''stack'' supports two operations: PUSH and POP. A command of the form “PUSH(A)” puts the key A at the top of the stack; the command “POP(X)” removes the top item from the stack and stores its value into variable X. If the stack was empty (because nothing had ever been pushed on it, or if all elements have been popped off of it), then X is given the special value of NIL. An analogy to this is a stack of books on a desk: a new book is placed on the top of the stack (pushed) and a book is removed from the top also (popped). Some textbooks call this data structure a “push-down stack” or a “LIFO stack”.<br />
<br />
''Queues'' operate just like stacks, except items are removed from the bottom instead of the top. A good physical analogy of this is the way a train conductor or newspaper boy uses a coin machine to give change: new coins are added to the tops of the piles, and change is given from the bottom of each. Some textbooks refer to this data structure as a “FIFO stack”.<br />
<br />
Consider the following sequence of 14 operations:<br />
<br />
<syntaxhighlight><br />
PUSH(A)<br />
PUSH(M)<br />
PUSH(E)<br />
POP(X)<br />
PUSH(R)<br />
POP(X)<br />
PUSH(I)<br />
POP(X)<br />
POP(X)<br />
POP(X)<br />
POP(X)<br />
PUSH(C)<br />
PUSH(A)<br />
PUSH(N)<br />
</syntaxhighlight><br />
<br />
If these operations are applied to a stack, then the values of the pops are: E, R, I, M, A and NIL. After all of the operations, there are three items still on the stack: the N is at the top (it will be the next to be popped, if nothing else is pushed before the pop command), and C is at the bottom. If, instead of using a stack we used a queue, then the values popped would be: A, M, E, R, I and NIL. There would be three items still on the queue: N at the top and C on the bottom. Since items are removed from the bottom of a queue, C would be the next item to be popped regardless of any additional pushes. Sometimes the top and bottom of a queue are referred to as the rear and the front respectively. Therefore, items are pushed/enqueued at the rear of the queue and popped/dequeued at the front of the queue. There is a similarity to the Britsh "queueing up".<br />
<br />
== Trees ==<br />
<br />
''Trees'', in general, use the following terminology: the ''root'' is the top node in the tree; ''children'' are the nodes that are immediately below a ''parent'' node; ''leaves'' are the bottom-most nodes on every branch of the tree; and ''siblings'' are nodes that have the same immediate parent. <br />
<br />
A ''binary search tree'' is composed of nodes having three parts: information (or a key), a pointer to a left child, and a pointer to a right child. It has the property that the key at every node is always greater than or equal to the key of its left child, and less than the key of its right child.<br />
<br />
The following tree is built from the keys A, M, E, R, I, C, A, N in that order:<br />
<br />
[[File:bst-american.svg|200px]]<br />
<br />
The ''root'' of the resulting tree is the node containing the key A; note that duplicate keys are inserted into the tree as if they were less than their equal key. This is the ACSL convention; in some textbooks and software libraries, duplicate keys may be considered larger than their equal key. The tree has a ''depth'' (sometimes called height) of 3 because the deepest node is 3 nodes below the root. The root node has a depth of 0. Nodes with no children are called leaf nodes; there are four of them in the tree: A, C, I and N. An ''external node'' is the name given to a place where a new node could be attached to the tree. (In some textbooks, a external node is synonymous with a leaf node. ) In the final tree above, there are 9 external nodes; these are not drawn. The tree has an ''internal path length'' of 15 which is the sum of the depths of all nodes. It has an ''external path length'' of 31 which is the sum of the depths of all external nodes. To insert the N (the last key inserted), 3 ''comparisons'' were needed against the root A (>), the M (>), and the R (≤).<br />
<br />
To perform an ''inorder'' traversal of the tree, recursively traverse the tree by first visiting the left child, then the root, then the right child. In the tree above, the nodes are visited in the following order: A, A, C, E, I, M, N, and R. A ''preorder'' travel (root, left, right) visits in the following order: A, A, M, E, C, I, R, and N. A ''postorder'' traversal (left, right, root) is: A, C, I, E, N, R, M, A. Inorder traversals are typically used to list the contents of the tree in sorted order. <br />
<br />
Binary search trees can support the operations insert, delete, and search. Moreover, it handles the operations efficiently; in a tree with 1 million items, one can search for a particular value in about log<sub>2</sub> 1000000 ≈ 20 steps. Items can be inserted or deleted in about as many steps, too. However, binary search trees can become unbalanced, if the keys being inserted are not pretty random. For example, consider the binary search tree resulting from inserting the keys A, E, I, O, U, Y. Sophisticated techniques are available to maintain balanced trees. Binary search trees are “dynamic” data structures that can support an unlimited number of operations in any order. <br />
<br />
To search for a node in a binary tree, the following algorithm (in pseudo-code) is used:<br />
<br />
<syntaxhighlight><br />
p = root<br />
found = FALSE<br />
while (p ≠ NIL) and (not found)<br />
if (x<p’s key)<br />
p = p’s left child<br />
else if (x>p’s key)<br />
p = p’s right child<br />
else<br />
found = TRUE<br />
end if<br />
end while<br />
</syntaxhighlight><br />
<br />
Deleting from a binary search tree is a bit more complicated. The algorithm we’ll use is as follows:<br />
<br />
<syntaxhighlight><br />
p = node to delete<br />
f = father of p<br />
if (p has no children)<br />
delete p<br />
else if (p has one child)<br />
make p’s child become f’s child<br />
delete p<br />
else if (p has two children)<br />
l = p’s left child (it might also have children)<br />
r = p’s right child (it might also have children)<br />
make l become f’s child instead of p<br />
stick r onto the l tree<br />
delete p<br />
end if<br />
</syntaxhighlight><br />
<br />
These diagrams illustrate the algorithm using the tree above. At the left, we delete I (0 children); in the middle, we delete the R (1 child); and at the right, we delete the M (2 children).<br />
<br />
{| class ="wikitable"<br />
|[[File:bst-american-del-i.svg|200px]]<br />
|[[File:bst-american-del-r.svg|200px]]<br />
|[[File:bst-american-del-m.svg|200px]] <br />
|}<br />
<br />
There are also general trees that use the same terminology, but they have 0 or more ''subnodes'' which can be accessed with an array or linked list of pointers. ''Pre-order'' and ''post-order'' traversals are possible with these trees, but the other algorithms do not work in the same way. Applications of general trees include game theory, organizational charts, family trees, etc.<br />
<br />
''Balanced'' trees minimize searching time when every leaf node has a depth of within 1 of every other leaf node. ''Complete'' trees are filled in at every level and are always balanced. ''Strictly binary'' trees ensure that every node has either 0 or 2 subnodes. You may want to consider how there are exactly 5 strictly binary trees with 7 nodes.<br />
<br />
== Priority Queues ==<br />
<br />
A ''priority queue'' is quite similar to a binary search tree, but one can only delete the smallest item and retrieve for the smallest. These insert and delete operations can be done in a guaranteed time proportional to the log of the number of items; the retrieve-the-smallest can be done in constant time. <br />
<br />
The standard way to implement a priority queue is using a ''heap'' data structure. A heap uses a binary tree (that is, a tree with two children) and maintains the following two properties: every node is smaller than its two children (nothing is said about the relative magnitude of the two children), and the resulting tree contains no “holes”. That is, all levels of the tree are completely filled, except the bottom level, which is filled in from the left to the right. <br />
<br />
The algorithm for insertion is not too difficult: put the new node at the bottom of the tree and then go up the tree, making exchanges with its parent, until the tree is valid. <br />
<!--here would be the place to show building the heap with AMERICAN--><br />
The heap at the left<br />
was building from the letters A, M, E, R, I, C, A, N (in that order); the heap at the right is after a C has been added.<br />
<br />
{| class="wikitable"<br />
|[[File:heap-american.svg|220px]]||<br />
[[File:heap-american-insert-c.svg|220px]]<br />
|}<br />
<br />
The smallest value is always the root. To delete it (and one can only delete the smallest value), one replaces it with the bottom-most and right-most element, and then walks down the tree making exchanges with the child in order to insure that the tree is valid. The following pseudo-code formalizes this notion:<br />
<br />
<syntaxhighlight><br />
b = bottom-most and right-most element<br />
p = root of tree<br />
p’s key = b’s key<br />
delete b<br />
while (p is larger than either child)<br />
exchange p with smaller child<br />
p = smaller child<br />
end while<br />
</syntaxhighlight><br />
<br />
When the smallest item is at the root of the heap, the heap is called a ''min-heap''. Of course, ''max-heaps'' are also possible and are common in practice. An efficient implementation of a heap uses an array, rather than a tree data structure.<br />
<br />
== Sample Problems ==<br />
<br />
=== Problem 1 ===<br />
<br />
Consider an initially empty stack. What is the value of Z when these operations are performed:<br />
<br />
<syntaxhighlight><br />
PUSH(3)<br />
PUSH(6)<br />
PUSH(8)<br />
POP(Y)<br />
POP(X)<br />
PUSH(X-Y)<br />
POP(Z) <br />
</syntaxhighlight><br />
<br />
'''Solution:''' The first POP(Y) stores 8 in Y. The POP(X) stores 6 in X. Then, 8-6=2 is pushed onto the stack. Finally, POP(Z) removes the 2 and stores it in Z.<br />
<br />
=== Problem 2 ===<br />
<br />
Create a min-heap with the letters in the word PROGRAMMING. What are the letters in the bottom-most row, from left to right?<br />
<br />
'''Solution:''' The bottom row contains the letters RORN, from left-to-right. Here is the entire heap:<br />
[[File:heap-programming.svg|200px]]<br />
<br />
=== Problem 3 ===<br />
<br />
Create a binary search tree from the letters in the word PROGRAMMING. What is the internal path length? <br />
<br />
Solution: When drawing the tree, P has a depth of 0, O and R have a depth of 1, G and R have a depth of 2, A and M have a depth of 3, M and N have a depth of 4, I has a depth of 5, and G has a depth of 6. Therefore, the internal path length is 31.<br />
<br />
= Video Resources =<br />
<br />
== ACSL Videos ==<br />
<br />
The following YouTube videos show ACSL students and advisors working out some ACSL problems that have appeared in previous contests. Some of the videos contain ads; ACSL is not responsible for the ads and does not receive compensation in any form for those ads. <br />
<br />
<!--<br />
{|<br />
|-<br />
| <youtube width="300" height="180">URL</youtube><br />
| [URL ''TITLE'' ('''AUTHOR''')]<br />
<br />
DESCRIPTION<br />
|}<br />
--><br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/gXj7K_petqo</youtube><br />
| [https://youtu.be/gXj7K_petqo ''Data Structures (Stacks and Queues)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on stacks and queues.<br />
<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/_BnbbOhyroQ</youtube><br />
| [https://youtu.be/_BnbbOhyroQ ''Construct a Binary Search Tree'' ('''Tangerine Code''')]<br />
<br />
Shows how to build a binary search tree from the letters '''S U S H I'''.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/l9aMO7lgHj0</youtube><br />
| [https://youtu.be/l9aMO7lgHj0 ''Binary Search Tree ACSL Problem (Internal Path Length)'' ('''Tangerine Code''')]<br />
<br />
A general tutorial on internal path length of a binary search tree<br />
|}<br />
<br />
== Other Videos ==<br />
<br />
There is no shortage of instructional video material covering basic data structures. Here is a series that combines teaching concepts with showing Java code that implements the concepts. Most of the ACSL questions will not involve coding the basic operations on the data structures; rather, the problems will involve high-level understanding of them. However, seeing the code is an excellent way to thoroughly understand these data structures, and what it takes to implement them.<br />
{|<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/wjI1WNcIntg</youtube><br />
| [https://youtu.be/wjI1WNcIntg ''Data Structures: Stacks and Queues'' ('''HackerRank''')]<br />
<br />
The first half of the video is a nice description of stacks and queues; the second half walks through very clean Java code that implements the fundamental methods on these data structures.<br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/njTh_OwMljA</youtube><br />
| [https://youtu.be/njTh_OwMljA ''Data Structures: Linked Lists'' ('''HackerRank''')]<br />
<br />
Although ACSL does not cover linked lists per se, they are a great preliminary study for binary search trees. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/oSWTXtMglKE</youtube><br />
| [https://youtu.be/oSWTXtMglKE ''Data Structures: Trees'' ('''HackerRank''')]<br />
<br />
Learn about binary search trees. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial''with Gayle Laakmann McDowell. The first half of the video is an clear and eloquent description of binary search trees; the second half walks through very clean Java code that implements the fundamental methods. <br />
|-<br />
| <youtube width="300" height="180">https://youtu.be/t0Cq6tVNRBA</youtube><br />
| [https://youtu.be/t0Cq6tVNRBA ''Data Structures: Heaps'' ('''HackerRank''')]<br />
<br />
Learn about heaps. This video is a part of HackerRank's ''Cracking The Coding Interview Tutorial'' with Gayle Laakmann McDowell. The first half of the video is an clear and eloquent description of heaps; the second half walks through very clean Java code that implements the fundamental methods. <br />
|}</div>Marc Brown