If your book is any good, it should mention **Karnaugh mapping**. Karnaugh mapping is about grouping like values (like all ones or all zeros) on a map consisting of rows and columns of logical combinations.  

![enter image description here][1]

If you can group logical combinations like that you can simplify your logical function as given in this example.  
  
Another method which works better for me is to work with **truth tables**. On the left you write all logical combinations of the inputs. For 3 inputs that would be  
  
>    A B C  
    0 0 0  
    0 0 1  
    0 1 0  
    0 1 1  
    1 0 0  
    1 0 1  
    1 1 0  
    1 1 1  

Note that this table becomes rather long if you have many inputs: \$2^N\$ lines. On the right you write the output(s). For example  
  
>    A B C  Y  
    0 0 0  1  
    0 0 1  0  
    0 1 0  1  
    0 1 1  0  
    1 0 0  0  
    1 0 1  1  
    1 1 0  0  
    1 1 1  1

With some exercise you often can see a pattern in the output. In this case for the first four lines, where A = 0, Y = B XOR C. For the rest, where A = 1, Y = NOT (B XOR C), or, combined: Y = A XOR B XOR C. (This can be used to create a parity bit)  
  
---
Jeff mentions how you can use DeMorgan's Law to create an OR gate from NANDs. This XOR gate is also basic:  
  
![XOR from NANDs][2]


  [1]: https://i.sstatic.net/ANJfp.jpg
  [2]: https://i.sstatic.net/zWTro.png