From 564179a0eca7ea56d640bcc1b2669113adbeec9e Mon Sep 17 00:00:00 2001 From: Alex Brown Date: Fri, 19 Oct 2018 07:48:28 -0500 Subject: [PATCH] increment 1 --- analysis/Compression_Analysis/PSNR.py | 38 + .../Compression_Analysis/compressed_image.png | Bin 0 -> 26684 bytes .../Compression_Analysis/example_image.jpg | Bin 0 -> 29986 bytes .../Compression_Analysis/orignal_image.png | Bin 0 -> 83865 bytes arithmetic_analysis/bisection.py | 33 + arithmetic_analysis/intersection.py | 16 + arithmetic_analysis/lu_decomposition.py | 34 + arithmetic_analysis/newton_method.py | 15 + arithmetic_analysis/newton_raphson_method.py | 36 + boolean_algebra/quine_mc_cluskey.py | 116 + ciphers/brute_force_caesar_cipher.py | 54 + ciphers/onepad_cipher.py | 32 + ciphers/prehistoric_men.txt | 7193 +++++++++++++++++ ...ansposition_cipher_encrypt_decrypt_file.py | 36 + ciphers/xor_cipher.py | 209 + data_structures/arrays.py | 3 + data_structures/avl.py | 181 + data_structures/binary tree/FenwickTree.py | 29 + .../binary tree/LazySegmentTree.py | 91 + data_structures/binary tree/SegmentTree.py | 71 + .../binary tree/binary_search_tree.py | 258 + data_structures/graph/bellman_ford.py | 54 + data_structures/graph/breadth_first_search.py | 67 + data_structures/graph/depth_first_search.py | 66 + data_structures/graph/dijkstra.py | 57 + data_structures/graph/dijkstra_algorithm.py | 212 + data_structures/graph/even_tree.py | 70 + data_structures/graph/floyd_warshall.py | 48 + data_structures/graph/graph.py | 44 + data_structures/graph/graph_list.py | 31 + data_structures/graph/graph_matrix.py | 32 + data_structures/heap/heap.py | 90 + .../linked_list/DoublyLinkedList.py | 76 + data_structures/linked_list/__init__.py | 22 + .../linked_list/singly_LinkedList.py | 70 + data_structures/queue/DeQueue.py | 40 + data_structures/queue/QueueOnList.py | 45 + data_structures/queue/QueueOnPseudoStack.py | 50 + data_structures/queue/__init__.py | 0 data_structures/stacks/Stock-Span-Problem.py | 52 + data_structures/stacks/__init__.py | 23 + .../stacks/balanced_parentheses.py | 23 + .../stacks/infix_to_postfix_conversion.py | 64 + data_structures/stacks/next.py | 17 + data_structures/stacks/stack.py | 69 + data_structures/trie/Trie.py | 75 + data_structures/union_find/__init__.py | 0 .../union_find/tests_union_find.py | 78 + data_structures/union_find/union_find.py | 87 + dynamic_programming/floyd_warshall.py | 37 + file_transfer_protocol/ftp_client_server.py | 58 + file_transfer_protocol/ftp_send_receive.py | 36 + graphs/ArticulationPoints.py | 44 + graphs/CheckBipartiteGraph_BFS.py | 43 + graphs/FindingBridges.py | 31 + graphs/KahnsAlgorithm_long.py | 30 + graphs/KahnsAlgorithm_topo.py | 32 + graphs/MinimumSpanningTree_Prims.py | 111 + graphs/Multi_Hueristic_Astar.py | 266 + graphs/a_star.py | 102 + graphs/basic-graphs.py | 281 + graphs/minimum_spanning_tree_kruskal.py | 32 + graphs/scc_kosaraju.py | 46 + graphs/tarjans_scc.py | 78 + linear_algebra_python/README.md | 74 + linear_algebra_python/src/lib.py | 364 + linear_algebra_python/src/tests.py | 133 + maths/BasicMaths.py | 74 + maths/FibonacciSequenceRecursion.py | 18 + maths/GreaterCommonDivisor.py | 15 + maths/ModularExponential.py | 20 + maths/SegmentedSieve.py | 46 + maths/SieveOfEratosthenes.py | 24 + maths/SimpsonRule.py | 49 + maths/TrapezoidalRule.py | 46 + neural_network/FCN.ipynb | 327 + neural_network/bpnn.py | 193 + neural_network/convolution_neural_network.py | 306 + neural_network/perceptron.py | 124 + project_euler/Problem 01/sol1.py | 17 + project_euler/Problem 01/sol2.py | 20 + project_euler/Problem 01/sol3.py | 50 + project_euler/Problem 01/sol4.py | 30 + project_euler/Problem 02/sol1.py | 26 + project_euler/Problem 02/sol2.py | 12 + project_euler/Problem 02/sol3.py | 20 + project_euler/Problem 03/sol1.py | 39 + project_euler/Problem 03/sol2.py | 17 + project_euler/Problem 04/sol1.py | 29 + project_euler/Problem 04/sol2.py | 19 + project_euler/Problem 05/sol1.py | 21 + project_euler/Problem 05/sol2.py | 20 + project_euler/Problem 06/sol1.py | 20 + project_euler/Problem 06/sol2.py | 16 + project_euler/Problem 07/sol1.py | 30 + project_euler/Problem 07/sol2.py | 16 + project_euler/Problem 08/sol1.py | 15 + project_euler/Problem 09/sol1.py | 15 + project_euler/Problem 09/sol2.py | 18 + project_euler/Problem 10/sol1.py | 38 + project_euler/Problem 11/grid.txt | 20 + project_euler/Problem 11/sol1.py | 68 + project_euler/Problem 11/sol2.py | 39 + project_euler/Problem 12/sol1.py | 46 + project_euler/Problem 13/sol1.py | 14 + project_euler/Problem 14/sol1.py | 21 + project_euler/Problem 15/sol1.py | 20 + project_euler/Problem 16/sol1.py | 15 + project_euler/Problem 17/sol1.py | 35 + project_euler/Problem 19/sol1.py | 51 + project_euler/Problem 20/sol1.py | 27 + project_euler/Problem 20/sol2.py | 5 + project_euler/Problem 21/sol1.py | 42 + project_euler/Problem 22/p022_names.txt | 1 + project_euler/Problem 22/sol1.py | 37 + project_euler/Problem 22/sol2.py | 533 ++ project_euler/Problem 24/sol1.py | 7 + project_euler/Problem 25/sol1.py | 31 + project_euler/Problem 28/sol1.py | 29 + project_euler/Problem 29/solution.py | 33 + project_euler/Problem 36/sol1.py | 30 + project_euler/Problem 40/sol1.py | 26 + project_euler/Problem 48/sol1.py | 21 + project_euler/Problem 52/sol1.py | 23 + project_euler/Problem 53/sol1.py | 36 + project_euler/Problem 76/sol1.py | 35 + project_euler/README.md | 58 + simple_client_server/README.md | 6 + simple_client_server/client.py | 14 + simple_client_server/server.py | 21 + tags | 1373 ++++ 131 files changed, 16252 insertions(+) create mode 100644 analysis/Compression_Analysis/PSNR.py create mode 100644 analysis/Compression_Analysis/compressed_image.png create mode 100644 analysis/Compression_Analysis/example_image.jpg create mode 100644 analysis/Compression_Analysis/orignal_image.png create mode 100644 arithmetic_analysis/bisection.py create mode 100644 arithmetic_analysis/intersection.py create mode 100644 arithmetic_analysis/lu_decomposition.py create mode 100644 arithmetic_analysis/newton_method.py create mode 100644 arithmetic_analysis/newton_raphson_method.py create mode 100644 boolean_algebra/quine_mc_cluskey.py create mode 100644 ciphers/brute_force_caesar_cipher.py create mode 100644 ciphers/onepad_cipher.py create mode 100644 ciphers/prehistoric_men.txt create mode 100644 ciphers/transposition_cipher_encrypt_decrypt_file.py create mode 100644 ciphers/xor_cipher.py create mode 100644 data_structures/arrays.py create mode 100644 data_structures/avl.py create mode 100644 data_structures/binary tree/FenwickTree.py create mode 100644 data_structures/binary tree/LazySegmentTree.py create mode 100644 data_structures/binary tree/SegmentTree.py create mode 100644 data_structures/binary tree/binary_search_tree.py create mode 100644 data_structures/graph/bellman_ford.py create mode 100644 data_structures/graph/breadth_first_search.py create mode 100644 data_structures/graph/depth_first_search.py create mode 100644 data_structures/graph/dijkstra.py create mode 100644 data_structures/graph/dijkstra_algorithm.py create mode 100644 data_structures/graph/even_tree.py create mode 100644 data_structures/graph/floyd_warshall.py create mode 100644 data_structures/graph/graph.py create mode 100644 data_structures/graph/graph_list.py create mode 100644 data_structures/graph/graph_matrix.py create mode 100644 data_structures/heap/heap.py create mode 100644 data_structures/linked_list/DoublyLinkedList.py create mode 100644 data_structures/linked_list/__init__.py create mode 100644 data_structures/linked_list/singly_LinkedList.py create mode 100644 data_structures/queue/DeQueue.py create mode 100644 data_structures/queue/QueueOnList.py create mode 100644 data_structures/queue/QueueOnPseudoStack.py create mode 100644 data_structures/queue/__init__.py create mode 100644 data_structures/stacks/Stock-Span-Problem.py create mode 100644 data_structures/stacks/__init__.py create mode 100644 data_structures/stacks/balanced_parentheses.py create mode 100644 data_structures/stacks/infix_to_postfix_conversion.py create mode 100644 data_structures/stacks/next.py create mode 100644 data_structures/stacks/stack.py create mode 100644 data_structures/trie/Trie.py create mode 100644 data_structures/union_find/__init__.py create mode 100644 data_structures/union_find/tests_union_find.py create mode 100644 data_structures/union_find/union_find.py create mode 100644 dynamic_programming/floyd_warshall.py create mode 100644 file_transfer_protocol/ftp_client_server.py create mode 100644 file_transfer_protocol/ftp_send_receive.py create mode 100644 graphs/ArticulationPoints.py create mode 100644 graphs/CheckBipartiteGraph_BFS.py create mode 100644 graphs/FindingBridges.py create mode 100644 graphs/KahnsAlgorithm_long.py create mode 100644 graphs/KahnsAlgorithm_topo.py create mode 100644 graphs/MinimumSpanningTree_Prims.py create mode 100644 graphs/Multi_Hueristic_Astar.py create mode 100644 graphs/a_star.py create mode 100644 graphs/basic-graphs.py create mode 100644 graphs/minimum_spanning_tree_kruskal.py create mode 100644 graphs/scc_kosaraju.py create mode 100644 graphs/tarjans_scc.py create mode 100644 linear_algebra_python/README.md create mode 100644 linear_algebra_python/src/lib.py create mode 100644 linear_algebra_python/src/tests.py create mode 100644 maths/BasicMaths.py create mode 100644 maths/FibonacciSequenceRecursion.py create mode 100644 maths/GreaterCommonDivisor.py create mode 100644 maths/ModularExponential.py create mode 100644 maths/SegmentedSieve.py create mode 100644 maths/SieveOfEratosthenes.py create mode 100644 maths/SimpsonRule.py create mode 100644 maths/TrapezoidalRule.py create mode 100644 neural_network/FCN.ipynb create mode 100644 neural_network/bpnn.py create mode 100644 neural_network/convolution_neural_network.py create mode 100644 neural_network/perceptron.py create mode 100644 project_euler/Problem 01/sol1.py create mode 100644 project_euler/Problem 01/sol2.py create mode 100644 project_euler/Problem 01/sol3.py create mode 100644 project_euler/Problem 01/sol4.py create mode 100644 project_euler/Problem 02/sol1.py create mode 100644 project_euler/Problem 02/sol2.py create mode 100644 project_euler/Problem 02/sol3.py create mode 100644 project_euler/Problem 03/sol1.py create mode 100644 project_euler/Problem 03/sol2.py create mode 100644 project_euler/Problem 04/sol1.py create mode 100644 project_euler/Problem 04/sol2.py create mode 100644 project_euler/Problem 05/sol1.py create mode 100644 project_euler/Problem 05/sol2.py create mode 100644 project_euler/Problem 06/sol1.py create mode 100644 project_euler/Problem 06/sol2.py create mode 100644 project_euler/Problem 07/sol1.py create mode 100644 project_euler/Problem 07/sol2.py create mode 100644 project_euler/Problem 08/sol1.py create mode 100644 project_euler/Problem 09/sol1.py create mode 100644 project_euler/Problem 09/sol2.py create mode 100644 project_euler/Problem 10/sol1.py create mode 100644 project_euler/Problem 11/grid.txt create mode 100644 project_euler/Problem 11/sol1.py create mode 100644 project_euler/Problem 11/sol2.py create mode 100644 project_euler/Problem 12/sol1.py create mode 100644 project_euler/Problem 13/sol1.py create mode 100644 project_euler/Problem 14/sol1.py create mode 100644 project_euler/Problem 15/sol1.py create mode 100644 project_euler/Problem 16/sol1.py create mode 100644 project_euler/Problem 17/sol1.py create mode 100644 project_euler/Problem 19/sol1.py create mode 100644 project_euler/Problem 20/sol1.py create mode 100644 project_euler/Problem 20/sol2.py create mode 100644 project_euler/Problem 21/sol1.py create mode 100644 project_euler/Problem 22/p022_names.txt create mode 100644 project_euler/Problem 22/sol1.py create mode 100644 project_euler/Problem 22/sol2.py create mode 100644 project_euler/Problem 24/sol1.py create mode 100644 project_euler/Problem 25/sol1.py create mode 100644 project_euler/Problem 28/sol1.py create mode 100644 project_euler/Problem 29/solution.py create mode 100644 project_euler/Problem 36/sol1.py create mode 100644 project_euler/Problem 40/sol1.py create mode 100644 project_euler/Problem 48/sol1.py create mode 100644 project_euler/Problem 52/sol1.py create mode 100644 project_euler/Problem 53/sol1.py create mode 100644 project_euler/Problem 76/sol1.py create mode 100644 project_euler/README.md create mode 100644 simple_client_server/README.md create mode 100644 simple_client_server/client.py create mode 100644 simple_client_server/server.py create mode 100644 tags diff --git a/analysis/Compression_Analysis/PSNR.py b/analysis/Compression_Analysis/PSNR.py new file mode 100644 index 000000000..1585c8cfc --- /dev/null +++ b/analysis/Compression_Analysis/PSNR.py @@ -0,0 +1,38 @@ +import numpy as np +import math +import cv2 + +def Representational(r,g,b): + return (0.299*r+0.287*g+0.114*b) + +def calculate(img): + b,g,r = cv2.split(img) + pixelAt = Representational(r,g,b) + return pixelAt + +def main(): + + #Loading images (orignal image and compressed image) + orignal_image = cv2.imread('orignal_image.png',1) + compressed_image = cv2.imread('compressed_image.png',1) + + #Getting image height and width + height,width = orignal_image.shape[:2] + + orignalPixelAt = calculate(orignal_image) + compressedPixelAt = calculate(compressed_image) + + diff = orignalPixelAt - compressedPixelAt + error = np.sum(np.abs(diff) ** 2) + + error = error/(height*width) + + #MSR = error_sum/(height*width) + PSNR = -(10*math.log10(error/(255*255))) + + print("PSNR value is {}".format(PSNR)) + + +if __name__ == '__main__': + main() + diff --git a/analysis/Compression_Analysis/compressed_image.png b/analysis/Compression_Analysis/compressed_image.png new file mode 100644 index 0000000000000000000000000000000000000000..75c41c21c7b579b88cedfbaee9ecaeb919db5683 GIT binary patch literal 26684 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Ð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 XP;3!Jj7l4S00000NkvXXu0mjfCMpBg literal 0 HcmV?d00001 diff --git a/analysis/Compression_Analysis/example_image.jpg b/analysis/Compression_Analysis/example_image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3a58ba3a8c338e08940c4494b4edd799294323e3 GIT binary patch literal 29986 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 z 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�Sb5QGN=^8)xhfJ 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 literal 0 HcmV?d00001 diff --git a/arithmetic_analysis/bisection.py b/arithmetic_analysis/bisection.py new file mode 100644 index 000000000..a6af547db --- /dev/null +++ b/arithmetic_analysis/bisection.py @@ -0,0 +1,33 @@ +import math + + +def bisection(function, a, b): # finds where the function becomes 0 in [a,b] using bolzano + + start = a + end = b + if function(a) == 0: # one of the a or b is a root for the function + return a + elif function(b) == 0: + return b + elif function(a) * function(b) > 0: # if none of these are root and they are both positive or negative, + # then his algorithm can't find the root + print("couldn't find root in [a,b]") + return + else: + mid = (start + end) / 2 + while abs(start - mid) > 0.0000001: # until we achieve precise equals to 10^-7 + if function(mid) == 0: + return mid + elif function(mid) * function(start) < 0: + end = mid + else: + start = mid + mid = (start + end) / 2 + return mid + + +def f(x): + return math.pow(x, 3) - 2*x - 5 + + +print(bisection(f, 1, 1000)) diff --git a/arithmetic_analysis/intersection.py b/arithmetic_analysis/intersection.py new file mode 100644 index 000000000..22c50f2ec --- /dev/null +++ b/arithmetic_analysis/intersection.py @@ -0,0 +1,16 @@ +import math + +def intersection(function,x0,x1): #function is the f we want to find its root and x0 and x1 are two random starting points + x_n = x0 + x_n1 = x1 + while True: + x_n2 = x_n1-(function(x_n1)/((function(x_n1)-function(x_n))/(x_n1-x_n))) + if abs(x_n2 - x_n1)<0.00001 : + return x_n2 + x_n=x_n1 + x_n1=x_n2 + +def f(x): + return math.pow(x,3)-2*x-5 + +print(intersection(f,3,3.5)) diff --git a/arithmetic_analysis/lu_decomposition.py b/arithmetic_analysis/lu_decomposition.py new file mode 100644 index 000000000..da05fb65d --- /dev/null +++ b/arithmetic_analysis/lu_decomposition.py @@ -0,0 +1,34 @@ +import numpy + +def LUDecompose (table): + #table that contains our data + #table has to be a square array so we need to check first + rows,columns=numpy.shape(table) + L=numpy.zeros((rows,columns)) + U=numpy.zeros((rows,columns)) + if rows!=columns: + return + for i in range (columns): + for j in range(i-1): + sum=0 + for k in range (j-1): + sum+=L[i][k]*U[k][j] + L[i][j]=(table[i][j]-sum)/U[j][j] + L[i][i]=1 + for j in range(i-1,columns): + sum1=0 + for k in range(i-1): + sum1+=L[i][k]*U[k][j] + U[i][j]=table[i][j]-sum1 + return L,U + + + + + + + +matrix =numpy.array([[2,-2,1],[0,1,2],[5,3,1]]) +L,U = LUDecompose(matrix) +print(L) +print(U) diff --git a/arithmetic_analysis/newton_method.py b/arithmetic_analysis/newton_method.py new file mode 100644 index 000000000..c3d5efb47 --- /dev/null +++ b/arithmetic_analysis/newton_method.py @@ -0,0 +1,15 @@ +def newton(function,function1,startingInt): #function is the f(x) and function1 is the f'(x) + x_n=startingInt + while True: + x_n1=x_n-function(x_n)/function1(x_n) + if abs(x_n-x_n1)<0.00001: + return x_n1 + x_n=x_n1 + +def f(x): + return (x**3)-2*x-5 + +def f1(x): + return 3*(x**2)-2 + +print(newton(f,f1,3)) diff --git a/arithmetic_analysis/newton_raphson_method.py b/arithmetic_analysis/newton_raphson_method.py new file mode 100644 index 000000000..5e7e2f930 --- /dev/null +++ b/arithmetic_analysis/newton_raphson_method.py @@ -0,0 +1,36 @@ +# Implementing Newton Raphson method in Python +# Author: Haseeb + +from sympy import diff +from decimal import Decimal + +def NewtonRaphson(func, a): + ''' Finds root from the point 'a' onwards by Newton-Raphson method ''' + while True: + c = Decimal(a) - ( Decimal(eval(func)) / Decimal(eval(str(diff(func)))) ) + + a = c + + # This number dictates the accuracy of the answer + if abs(eval(func)) < 10**-15: + return c + + +# Let's Execute +if __name__ == '__main__': + # Find root of trigonometric function + # Find value of pi + print ('sin(x) = 0', NewtonRaphson('sin(x)', 2)) + + # Find root of polynomial + print ('x**2 - 5*x +2 = 0', NewtonRaphson('x**2 - 5*x +2', 0.4)) + + # Find Square Root of 5 + print ('x**2 - 5 = 0', NewtonRaphson('x**2 - 5', 0.1)) + + # Exponential Roots + print ('exp(x) - 1 = 0', NewtonRaphson('exp(x) - 1', 0)) + + + + diff --git a/boolean_algebra/quine_mc_cluskey.py b/boolean_algebra/quine_mc_cluskey.py new file mode 100644 index 000000000..ff2df5117 --- /dev/null +++ b/boolean_algebra/quine_mc_cluskey.py @@ -0,0 +1,116 @@ +def compare_string(string1, string2): + l1 = list(string1); l2 = list(string2) + count = 0 + for i in range(len(l1)): + if l1[i] != l2[i]: + count += 1 + l1[i] = '_' + if count > 1: + return -1 + else: + return("".join(l1)) + +def check(binary): + pi = [] + while 1: + check1 = ['$']*len(binary) + temp = [] + for i in range(len(binary)): + for j in range(i+1, len(binary)): + k=compare_string(binary[i], binary[j]) + if k != -1: + check1[i] = '*' + check1[j] = '*' + temp.append(k) + for i in range(len(binary)): + if check1[i] == '$': + pi.append(binary[i]) + if len(temp) == 0: + return pi + binary = list(set(temp)) + +def decimal_to_binary(no_of_variable, minterms): + temp = [] + s = '' + for m in minterms: + for i in range(no_of_variable): + s = str(m%2) + s + m //= 2 + temp.append(s) + s = '' + return temp + +def is_for_table(string1, string2, count): + l1 = list(string1);l2=list(string2) + count_n = 0 + for i in range(len(l1)): + if l1[i] != l2[i]: + count_n += 1 + if count_n == count: + return True + else: + return False + +def selection(chart, prime_implicants): + temp = [] + select = [0]*len(chart) + for i in range(len(chart[0])): + count = 0 + rem = -1 + for j in range(len(chart)): + if chart[j][i] == 1: + count += 1 + rem = j + if count == 1: + select[rem] = 1 + for i in range(len(select)): + if select[i] == 1: + for j in range(len(chart[0])): + if chart[i][j] == 1: + for k in range(len(chart)): + chart[k][j] = 0 + temp.append(prime_implicants[i]) + while 1: + max_n = 0; rem = -1; count_n = 0 + for i in range(len(chart)): + count_n = chart[i].count(1) + if count_n > max_n: + max_n = count_n + rem = i + + if max_n == 0: + return temp + + temp.append(prime_implicants[rem]) + + for i in range(len(chart[0])): + if chart[rem][i] == 1: + for j in range(len(chart)): + chart[j][i] = 0 + +def prime_implicant_chart(prime_implicants, binary): + chart = [[0 for x in range(len(binary))] for x in range(len(prime_implicants))] + for i in range(len(prime_implicants)): + count = prime_implicants[i].count('_') + for j in range(len(binary)): + if(is_for_table(prime_implicants[i], binary[j], count)): + chart[i][j] = 1 + + return chart + +def main(): + no_of_variable = int(raw_input("Enter the no. of variables\n")) + minterms = [int(x) for x in raw_input("Enter the decimal representation of Minterms 'Spaces Seprated'\n").split()] + binary = decimal_to_binary(no_of_variable, minterms) + + prime_implicants = check(binary) + print("Prime Implicants are:") + print(prime_implicants) + chart = prime_implicant_chart(prime_implicants, binary) + + essential_prime_implicants = selection(chart,prime_implicants) + print("Essential Prime Implicants are:") + print(essential_prime_implicants) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/ciphers/brute_force_caesar_cipher.py b/ciphers/brute_force_caesar_cipher.py new file mode 100644 index 000000000..8582249c8 --- /dev/null +++ b/ciphers/brute_force_caesar_cipher.py @@ -0,0 +1,54 @@ +from __future__ import print_function +def decrypt(message): + """ + >>> decrypt('TMDETUX PMDVU') + Decryption using Key #0: TMDETUX PMDVU + Decryption using Key #1: SLCDSTW OLCUT + Decryption using Key #2: RKBCRSV NKBTS + Decryption using Key #3: QJABQRU MJASR + Decryption using Key #4: PIZAPQT LIZRQ + Decryption using Key #5: OHYZOPS KHYQP + Decryption using Key #6: NGXYNOR JGXPO + Decryption using Key #7: MFWXMNQ IFWON + Decryption using Key #8: LEVWLMP HEVNM + Decryption using Key #9: KDUVKLO GDUML + Decryption using Key #10: JCTUJKN FCTLK + Decryption using Key #11: IBSTIJM EBSKJ + Decryption using Key #12: HARSHIL DARJI + Decryption using Key #13: GZQRGHK CZQIH + Decryption using Key #14: FYPQFGJ BYPHG + Decryption using Key #15: EXOPEFI AXOGF + Decryption using Key #16: DWNODEH ZWNFE + Decryption using Key #17: CVMNCDG YVMED + Decryption using Key #18: BULMBCF XULDC + Decryption using Key #19: ATKLABE WTKCB + Decryption using Key #20: ZSJKZAD VSJBA + Decryption using Key #21: YRIJYZC URIAZ + Decryption using Key #22: XQHIXYB TQHZY + Decryption using Key #23: WPGHWXA SPGYX + Decryption using Key #24: VOFGVWZ ROFXW + Decryption using Key #25: UNEFUVY QNEWV + """ + LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + for key in range(len(LETTERS)): + translated = "" + for symbol in message: + if symbol in LETTERS: + num = LETTERS.find(symbol) + num = num - key + if num < 0: + num = num + len(LETTERS) + translated = translated + LETTERS[num] + else: + translated = translated + symbol + print("Decryption using Key #%s: %s" % (key, translated)) + +def main(): + message = raw_input("Encrypted message: ") + message = message.upper() + decrypt(message) + +if __name__ == '__main__': + import doctest + doctest.testmod() + main() diff --git a/ciphers/onepad_cipher.py b/ciphers/onepad_cipher.py new file mode 100644 index 000000000..7e1be5fdc --- /dev/null +++ b/ciphers/onepad_cipher.py @@ -0,0 +1,32 @@ +from __future__ import print_function + +import random + + +class Onepad: + def encrypt(self, text): + '''Function to encrypt text using psedo-random numbers''' + plain = [ord(i) for i in text] + key = [] + cipher = [] + for i in plain: + k = random.randint(1, 300) + c = (i+k)*k + cipher.append(c) + key.append(k) + return cipher, key + + def decrypt(self, cipher, key): + '''Function to decrypt text using psedo-random numbers.''' + plain = [] + for i in range(len(key)): + p = (cipher[i]-(key[i])**2)/key[i] + plain.append(chr(p)) + plain = ''.join([i for i in plain]) + return plain + + +if __name__ == '__main__': + c, k = Onepad().encrypt('Hello') + print(c, k) + print(Onepad().decrypt(c, k)) diff --git a/ciphers/prehistoric_men.txt b/ciphers/prehistoric_men.txt new file mode 100644 index 000000000..86c4de821 --- /dev/null +++ b/ciphers/prehistoric_men.txt @@ -0,0 +1,7193 @@ +The Project Gutenberg eBook, Prehistoric Men, by Robert J. (Robert John) +Braidwood, Illustrated by Susan T. Richert + + +This eBook is for the use of anyone anywhere in the United States and most +other parts of the world at no cost and with almost no restrictions +whatsoever. You may copy it, give it away or re-use it under the terms of +the Project Gutenberg License included with this eBook or online at +www.gutenberg.org. If you are not located in the United States, you'll have +to check the laws of the country where you are located before using this ebook. + + +Title: Prehistoric Men +Author: Robert J. (Robert John) Braidwood +Release Date: July 28, 2016 [eBook #52664] +Language: English +Character set encoding: UTF-8 + + +***START OF THE PROJECT GUTENBERG EBOOK PREHISTORIC MEN*** + + +E-text prepared by Stephen Hutcheson, Dave Morgan, Charlie Howard, and the +Online Distributed Proofreading Team (http://www.pgdp.net) + + + +Note: Project Gutenberg also has an HTML version of this + file which includes the original illustrations. + See 52664-h.htm or 52664-h.zip: + (http://www.gutenberg.org/files/52664/52664-h/52664-h.htm) + or + (http://www.gutenberg.org/files/52664/52664-h.zip) + + +Transcriber's note: + + Some characters might not display in this UTF-8 text + version. If so, the reader should consult the HTML + version referred to above. One example of this might + occur in the second paragraph under "Choppers and + Adze-like Tools", page 46, which contains the phrase + “an adze cutting edge is ? shaped”. The symbol before + “shaped” looks like a sharply-italicized sans-serif “L”. + Devices that cannot display that symbol may substitute + a question mark, a square, or other symbol. + + +PREHISTORIC MEN + +by + +ROBERT J. BRAIDWOOD + +Research Associate, Old World Prehistory + +Professor +Oriental Institute and Department of Anthropology +University of Chicago + +Drawings by Susan T. Richert + + +[Illustration] + +Chicago Natural History Museum +Popular Series +Anthropology, Number 37 + +Third Edition Issued in Co-operation with +The Oriental Institute, The University of Chicago + +Edited by Lillian A. Ross + +Printed in the United States of America +by Chicago Natural History Museum Press + +Copyright 1948, 1951, and 1957 by Chicago Natural History Museum + +First edition 1948 +Second edition 1951 +Third edition 1957 +Fourth edition 1959 + + +Preface + +[Illustration] + + +Like the writing of most professional archeologists, mine has been +confined to so-called learned papers. Good, bad, or indifferent, these +papers were in a jargon that only my colleagues and a few advanced +students could understand. Hence, when I was asked to do this little +book, I soon found it extremely difficult to say what I meant in simple +fashion. The style is new to me, but I hope the reader will not find it +forced or pedantic; at least I have done my very best to tell the story +simply and clearly. + +Many friends have aided in the preparation of the book. The whimsical +charm of Miss Susan Richert’s illustrations add enormously to the +spirit I wanted. She gave freely of her own time on the drawings and +in planning the book with me. My colleagues at the University of +Chicago, especially Professor Wilton M. Krogman (now of the University +of Pennsylvania), and also Mrs. Linda Braidwood, Associate of the +Oriental Institute, and Professors Fay-Cooper Cole and Sol Tax, of +the Department of Anthropology, gave me counsel in matters bearing on +their special fields, and the Department of Anthropology bore some of +the expense of the illustrations. From Mrs. Irma Hunter and Mr. Arnold +Maremont, who are not archeologists at all and have only an intelligent +layman’s notion of archeology, I had sound advice on how best to tell +the story. I am deeply indebted to all these friends. + +While I was preparing the second edition, I had the great fortune +to be able to rework the third chapter with Professor Sherwood L. +Washburn, now of the Department of Anthropology of the University of +California, and the fourth, fifth, and sixth chapters with Professor +Hallum L. Movius, Jr., of the Peabody Museum, Harvard University. The +book has gained greatly in accuracy thereby. In matters of dating, +Professor Movius and the indications of Professor W. F. Libby’s Carbon +14 chronology project have both encouraged me to choose the lowest +dates now current for the events of the Pleistocene Ice Age. There is +still no certain way of fixing a direct chronology for most of the +Pleistocene, but Professor Libby’s method appears very promising for +its end range and for proto-historic dates. In any case, this book +names “periods,” and new dates may be written in against mine, if new +and better dating systems appear. + +I wish to thank Dr. Clifford C. Gregg, Director of Chicago Natural +History Museum, for the opportunity to publish this book. My old +friend, Dr. Paul S. Martin, Chief Curator in the Department of +Anthropology, asked me to undertake the job and inspired me to complete +it. I am also indebted to Miss Lillian A. Ross, Associate Editor of +Scientific Publications, and to Mr. George I. Quimby, Curator of +Exhibits in Anthropology, for all the time they have given me in +getting the manuscript into proper shape. + + ROBERT J. BRAIDWOOD + _June 15, 1950_ + + + + +Preface to the Third Edition + + +In preparing the enlarged third edition, many of the above mentioned +friends have again helped me. I have picked the brains of Professor F. +Clark Howell of the Department of Anthropology of the University of +Chicago in reworking the earlier chapters, and he was very patient in +the matter, which I sincerely appreciate. + +All of Mrs. Susan Richert Allen’s original drawings appear, but a few +necessary corrections have been made in some of the charts and some new +drawings have been added by Mr. John Pfiffner, Staff Artist, Chicago +Natural History Museum. + + ROBERT J. BRAIDWOOD + _March 1, 1959_ + + + + +Contents + + + PAGE + How We Learn about Prehistoric Men 7 + + The Changing World in Which Prehistoric Men Lived 17 + + Prehistoric Men Themselves 22 + + Cultural Beginnings 38 + + More Evidence of Culture 56 + + Early Moderns 70 + + End and Prelude 92 + + The First Revolution 121 + + The Conquest of Civilization 144 + + End of Prehistory 162 + + Summary 176 + + List of Books 180 + + Index 184 + + + + +HOW WE LEARN about Prehistoric Men + +[Illustration] + + +Prehistory means the time before written history began. Actually, more +than 99 per cent of man’s story is prehistory. Man is at least half a +million years old, but he did not begin to write history (or to write +anything) until about 5,000 years ago. + +The men who lived in prehistoric times left us no history books, but +they did unintentionally leave a record of their presence and their way +of life. This record is studied and interpreted by different kinds of +scientists. + + +SCIENTISTS WHO FIND OUT ABOUT PREHISTORIC MEN + +The scientists who study the bones and teeth and any other parts +they find of the bodies of prehistoric men, are called _physical +anthropologists_. Physical anthropologists are trained, much like +doctors, to know all about the human body. They study living people, +too; they know more about the biological facts of human “races” than +anybody else. If the police find a badly decayed body in a trunk, +they ask a physical anthropologist to tell them what the person +originally looked like. The physical anthropologists who specialize in +prehistoric men work with fossils, so they are sometimes called _human +paleontologists_. + + +ARCHEOLOGISTS + +There is a kind of scientist who studies the things that prehistoric +men made and did. Such a scientist is called an _archeologist_. It is +the archeologist’s business to look for the stone and metal tools, the +pottery, the graves, and the caves or huts of the men who lived before +history began. + +But there is more to archeology than just looking for things. In +Professor V. Gordon Childe’s words, archeology “furnishes a sort of +history of human activity, provided always that the actions have +produced concrete results and left recognizable material traces.” You +will see that there are at least three points in what Childe says: + + 1. The archeologists have to find the traces of things left behind by + ancient man, and + + 2. Only a few objects may be found, for most of these were probably + too soft or too breakable to last through the years. However, + + 3. The archeologist must use whatever he can find to tell a story--to + make a “sort of history”--from the objects and living-places and + graves that have escaped destruction. + +What I mean is this: Let us say you are walking through a dump yard, +and you find a rusty old spark plug. If you want to think about what +the spark plug means, you quickly remember that it is a part of an +automobile motor. This tells you something about the man who threw +the spark plug on the dump. He either had an automobile, or he knew +or lived near someone who did. He can’t have lived so very long ago, +you’ll remember, because spark plugs and automobiles are only about +sixty years old. + +When you think about the old spark plug in this way you have +just been making the beginnings of what we call an archeological +_interpretation_; you have been making the spark plug tell a story. +It is the same way with the man-made things we archeologists find +and put in museums. Usually, only a few of these objects are pretty +to look at; but each of them has some sort of story to tell. Making +the interpretation of his finds is the most important part of the +archeologist’s job. It is the way he gets at the “sort of history of +human activity” which is expected of archeology. + + +SOME OTHER SCIENTISTS + +There are many other scientists who help the archeologist and the +physical anthropologist find out about prehistoric men. The geologists +help us tell the age of the rocks or caves or gravel beds in which +human bones or man-made objects are found. There are other scientists +with names which all begin with “paleo” (the Greek word for “old”). The +_paleontologists_ study fossil animals. There are also, for example, +such scientists as _paleobotanists_ and _paleoclimatologists_, who +study ancient plants and climates. These scientists help us to know +the kinds of animals and plants that were living in prehistoric times +and so could be used for food by ancient man; what the weather was +like; and whether there were glaciers. Also, when I tell you that +prehistoric men did not appear until long after the great dinosaurs had +disappeared, I go on the say-so of the paleontologists. They know that +fossils of men and of dinosaurs are not found in the same geological +period. The dinosaur fossils come in early periods, the fossils of men +much later. + +Since World War II even the atomic scientists have been helping the +archeologists. By testing the amount of radioactivity left in charcoal, +wood, or other vegetable matter obtained from archeological sites, they +have been able to date the sites. Shell has been used also, and even +the hair of Egyptian mummies. The dates of geological and climatic +events have also been discovered. Some of this work has been done from +drillings taken from the bottom of the sea. + +This dating by radioactivity has considerably shortened the dates which +the archeologists used to give. If you find that some of the dates +I give here are more recent than the dates you see in other books +on prehistory, it is because I am using one of the new lower dating +systems. + +[Illustration: RADIOCARBON CHART + +The rate of disappearance of radioactivity as time passes.[1]] + + [1] It is important that the limitations of the radioactive carbon + “dating” system be held in mind. As the statistics involved in + the system are used, there are two chances in three that the + “date” of the sample falls within the range given as plus or + minus an added number of years. For example, the “date” for the + Jarmo village (see chart), given as 6750 ± 200 B.C., really + means that there are only two chances in three that the real + date of the charcoal sampled fell between 6950 and 6550 B.C. + We have also begun to suspect that there are ways in which the + samples themselves may have become “contaminated,” either on + the early or on the late side. We now tend to be suspicious of + single radioactive carbon determinations, or of determinations + from one site alone. But as a fabric of consistent + determinations for several or more sites of one archeological + period, we gain confidence in the “dates.” + + +HOW THE SCIENTISTS FIND OUT + +So far, this chapter has been mainly about the people who find out +about prehistoric men. We also need a word about _how_ they find out. + +All our finds came by accident until about a hundred years ago. Men +digging wells, or digging in caves for fertilizer, often turned up +ancient swords or pots or stone arrowheads. People also found some odd +pieces of stone that didn’t look like natural forms, but they also +didn’t look like any known tool. As a result, the people who found them +gave them queer names; for example, “thunderbolts.” The people thought +the strange stones came to earth as bolts of lightning. We know now +that these strange stones were prehistoric stone tools. + +Many important finds still come to us by accident. In 1935, a British +dentist, A. T. Marston, found the first of two fragments of a very +important fossil human skull, in a gravel pit at Swanscombe, on the +River Thames, England. He had to wait nine months, until the face of +the gravel pit had been dug eight yards farther back, before the second +fragment appeared. They fitted! Then, twenty years later, still another +piece appeared. In 1928 workmen who were blasting out rock for the +breakwater in the port of Haifa began to notice flint tools. Thus the +story of cave men on Mount Carmel, in Palestine, began to be known. + +Planned archeological digging is only about a century old. Even before +this, however, a few men realized the significance of objects they dug +from the ground; one of these early archeologists was our own Thomas +Jefferson. The first real mound-digger was a German grocer’s clerk, +Heinrich Schliemann. Schliemann made a fortune as a merchant, first +in Europe and then in the California gold-rush of 1849. He became an +American citizen. Then he retired and had both money and time to test +an old idea of his. He believed that the heroes of ancient Troy and +Mycenae were once real Trojans and Greeks. He proved it by going to +Turkey and Greece and digging up the remains of both cities. + +Schliemann had the great good fortune to find rich and spectacular +treasures, and he also had the common sense to keep notes and make +descriptions of what he found. He proved beyond doubt that many ancient +city mounds can be _stratified_. This means that there may be the +remains of many towns in a mound, one above another, like layers in a +cake. + +You might like to have an idea of how mounds come to be in layers. +The original settlers may have chosen the spot because it had a good +spring and there were good fertile lands nearby, or perhaps because +it was close to some road or river or harbor. These settlers probably +built their town of stone and mud-brick. Finally, something would have +happened to the town--a flood, or a burning, or a raid by enemies--and +the walls of the houses would have fallen in or would have melted down +as mud in the rain. Nothing would have remained but the mud and debris +of a low mound of _one_ layer. + +The second settlers would have wanted the spot for the same reasons +the first settlers did--good water, land, and roads. Also, the second +settlers would have found a nice low mound to build their houses on, +a protection from floods. But again, something would finally have +happened to the second town, and the walls of _its_ houses would have +come tumbling down. This makes the _second_ layer. And so on.... + +In Syria I once had the good fortune to dig on a large mound that had +no less than fifteen layers. Also, most of the layers were thick, and +there were signs of rebuilding and repairs within each layer. The mound +was more than a hundred feet high. In each layer, the building material +used had been a soft, unbaked mud-brick, and most of the debris +consisted of fallen or rain-melted mud from these mud-bricks. + +This idea of _stratification_, like the cake layers, was already a +familiar one to the geologists by Schliemann’s time. They could show +that their lowest layer of rock was oldest or earliest, and that the +overlying layers became more recent as one moved upward. Schliemann’s +digging proved the same thing at Troy. His first (lowest and earliest) +city had at least nine layers above it; he thought that the second +layer contained the remains of Homer’s Troy. We now know that Homeric +Troy was layer VIIa from the bottom; also, we count eleven layers or +sub-layers in total. + +Schliemann’s work marks the beginnings of modern archeology. Scholars +soon set out to dig on ancient sites, from Egypt to Central America. + + +ARCHEOLOGICAL INFORMATION + +As time went on, the study of archeological materials--found either +by accident or by digging on purpose--began to show certain things. +Archeologists began to get ideas as to the kinds of objects that +belonged together. If you compared a mail-order catalogue of 1890 with +one of today, you would see a lot of differences. If you really studied +the two catalogues hard, you would also begin to see that certain +objects “go together.” Horseshoes and metal buggy tires and pieces of +harness would begin to fit into a picture with certain kinds of coal +stoves and furniture and china dishes and kerosene lamps. Our friend +the spark plug, and radios and electric refrigerators and light bulbs +would fit into a picture with different kinds of furniture and dishes +and tools. You won’t be old enough to remember the kind of hats that +women wore in 1890, but you’ve probably seen pictures of them, and you +know very well they couldn’t be worn with the fashions of today. + +This is one of the ways that archeologists study their materials. +The various tools and weapons and jewelry, the pottery, the kinds +of houses, and even the ways of burying the dead tend to fit into +pictures. Some archeologists call all of the things that go together to +make such a picture an _assemblage_. The assemblage of the first layer +of Schliemann’s Troy was as different from that of the seventh layer as +our 1900 mail-order catalogue is from the one of today. + +The archeologists who came after Schliemann began to notice other +things and to compare them with occurrences in modern times. The +idea that people will buy better mousetraps goes back into very +ancient times. Today, if we make good automobiles or radios, we can +sell some of them in Turkey or even in Timbuktu. This means that a +few present-day types of American automobiles and radios form part +of present-day “assemblages” in both Turkey and Timbuktu. The total +present-day “assemblage” of Turkey is quite different from that of +Timbuktu or that of America, but they have at least some automobiles +and some radios in common. + +Now these automobiles and radios will eventually wear out. Let us +suppose we could go to some remote part of Turkey or to Timbuktu in a +dream. We don’t know what the date is, in our dream, but we see all +sorts of strange things and ways of living in both places. Nobody +tells us what the date is. But suddenly we see a 1936 Ford; so we +know that in our dream it has to be at least the year 1936, and only +as many years after that as we could reasonably expect a Ford to keep +in running order. The Ford would probably break down in twenty years’ +time, so the Turkish or Timbuktu “assemblage” we’re seeing in our dream +has to date at about A.D. 1936-56. + +Archeologists not only “date” their ancient materials in this way; they +also see over what distances and between which peoples trading was +done. It turns out that there was a good deal of trading in ancient +times, probably all on a barter and exchange basis. + + +EVERYTHING BEGINS TO FIT TOGETHER + +Now we need to pull these ideas all together and see the complicated +structure the archeologists can build with their materials. + +Even the earliest archeologists soon found that there was a very long +range of prehistoric time which would yield only very simple things. +For this very long early part of prehistory, there was little to be +found but the flint tools which wandering, hunting and gathering +people made, and the bones of the wild animals they ate. Toward the +end of prehistoric time there was a general settling down with the +coming of agriculture, and all sorts of new things began to be made. +Archeologists soon got a general notion of what ought to appear with +what. Thus, it would upset a French prehistorian digging at the bottom +of a very early cave if he found a fine bronze sword, just as much as +it would upset him if he found a beer bottle. The people of his very +early cave layer simply could not have made bronze swords, which came +later, just as do beer bottles. Some accidental disturbance of the +layers of his cave must have happened. + +With any luck, archeologists do their digging in a layered, stratified +site. They find the remains of everything that would last through +time, in several different layers. They know that the assemblage in +the bottom layer was laid down earlier than the assemblage in the next +layer above, and so on up to the topmost layer, which is the latest. +They look at the results of other “digs” and find that some other +archeologist 900 miles away has found ax-heads in his lowest layer, +exactly like the ax-heads of their fifth layer. This means that their +fifth layer must have been lived in at about the same time as was the +first layer in the site 200 miles away. It also may mean that the +people who lived in the two layers knew and traded with each other. Or +it could mean that they didn’t necessarily know each other, but simply +that both traded with a third group at about the same time. + +You can see that the more we dig and find, the more clearly the main +facts begin to stand out. We begin to be more sure of which people +lived at the same time, which earlier and which later. We begin to +know who traded with whom, and which peoples seemed to live off by +themselves. We begin to find enough skeletons in burials so that the +physical anthropologists can tell us what the people looked like. We +get animal bones, and a paleontologist may tell us they are all bones +of wild animals; or he may tell us that some or most of the bones are +those of domesticated animals, for instance, sheep or cattle, and +therefore the people must have kept herds. + +More important than anything else--as our structure grows more +complicated and our materials increase--is the fact that “a sort +of history of human activity” does begin to appear. The habits or +traditions that men formed in the making of their tools and in the +ways they did things, begin to stand out for us. How characteristic +were these habits and traditions? What areas did they spread over? +How long did they last? We watch the different tools and the traces +of the way things were done--how the burials were arranged, what +the living-places were like, and so on. We wonder about the people +themselves, for the traces of habits and traditions are useful to us +only as clues to the men who once had them. So we ask the physical +anthropologists about the skeletons that we found in the burials. The +physical anthropologists tell us about the anatomy and the similarities +and differences which the skeletons show when compared with other +skeletons. The physical anthropologists are even working on a +method--chemical tests of the bones--that will enable them to discover +what the blood-type may have been. One thing is sure. We have never +found a group of skeletons so absolutely similar among themselves--so +cast from a single mould, so to speak--that we could claim to have a +“pure” race. I am sure we never shall. + +We become particularly interested in any signs of change--when new +materials and tool types and ways of doing things replace old ones. We +watch for signs of social change and progress in one way or another. + +We must do all this without one word of written history to aid us. +Everything we are concerned with goes back to the time _before_ men +learned to write. That is the prehistorian’s job--to find out what +happened before history began. + + + + +THE CHANGING WORLD in which Prehistoric Men Lived + +[Illustration] + + +Mankind, we’ll say, is at least a half million years old. It is very +hard to understand how long a time half a million years really is. +If we were to compare this whole length of time to one day, we’d get +something like this: The present time is midnight, and Jesus was +born just five minutes and thirty-six seconds ago. Earliest history +began less than fifteen minutes ago. Everything before 11:45 was in +prehistoric time. + +Or maybe we can grasp the length of time better in terms of +generations. As you know, primitive peoples tend to marry and have +children rather early in life. So suppose we say that twenty years +will make an average generation. At this rate there would be 25,000 +generations in a half-million years. But our United States is much less +than ten generations old, twenty-five generations take us back before +the time of Columbus, Julius Caesar was alive just 100 generations ago, +David was king of Israel less than 150 generations ago, 250 generations +take us back to the beginning of written history. And there were 24,750 +generations of men before written history began! + +I should probably tell you that there is a new method of prehistoric +dating which would cut the earliest dates in my reckoning almost +in half. Dr. Cesare Emiliani, combining radioactive (C14) and +chemical (oxygen isotope) methods in the study of deep-sea borings, +has developed a system which would lower the total range of human +prehistory to about 300,000 years. The system is still too new to have +had general examination and testing. Hence, I have not used it in this +book; it would mainly affect the dates earlier than 25,000 years ago. + + +CHANGES IN ENVIRONMENT + +The earth probably hasn’t changed much in the last 5,000 years (250 +generations). Men have built things on its surface and dug into it and +drawn boundaries on maps of it, but the places where rivers, lakes, +seas, and mountains now stand have changed very little. + +In earlier times the earth looked very different. Geologists call the +last great geological period the _Pleistocene_. It began somewhere +between a half million and a million years ago, and was a time of great +changes. Sometimes we call it the Ice Age, for in the Pleistocene +there were at least three or four times when large areas of earth +were covered with glaciers. The reason for my uncertainty is that +while there seem to have been four major mountain or alpine phases of +glaciation, there may only have been three general continental phases +in the Old World.[2] + + [2] This is a complicated affair and I do not want to bother you + with its details. Both the alpine and the continental ice sheets + seem to have had minor fluctuations during their _main_ phases, + and the advances of the later phases destroyed many of the + traces of the earlier phases. The general textbooks have tended + to follow the names and numbers established for the Alps early + in this century by two German geologists. I will not bother you + with the names, but there were _four_ major phases. It is the + second of these alpine phases which seems to fit the traces of + the earliest of the great continental glaciations. In this book, + I will use the four-part system, since it is the most familiar, + but will add the word _alpine_ so you may remember to make the + transition to the continental system if you wish to do so. + +Glaciers are great sheets of ice, sometimes over a thousand feet +thick, which are now known only in Greenland and Antarctica and in +high mountains. During several of the glacial periods in the Ice Age, +the glaciers covered most of Canada and the northern United States and +reached down to southern England and France in Europe. Smaller ice +sheets sat like caps on the Rockies, the Alps, and the Himalayas. The +continental glaciation only happened north of the equator, however, so +remember that “Ice Age” is only half true. + +As you know, the amount of water on and about the earth does not vary. +These large glaciers contained millions of tons of water frozen into +ice. Because so much water was frozen and contained in the glaciers, +the water level of lakes and oceans was lowered. Flooded areas were +drained and appeared as dry land. There were times in the Ice Age when +there was no English Channel, so that England was not an island, and a +land bridge at the Dardanelles probably divided the Mediterranean from +the Black Sea. + +A very important thing for people living during the time of a +glaciation was the region adjacent to the glacier. They could not, of +course, live on the ice itself. The questions would be how close could +they live to it, and how would they have had to change their way of +life to do so. + + +GLACIERS CHANGE THE WEATHER + +Great sheets of ice change the weather. When the front of a glacier +stood at Milwaukee, the weather must have been bitterly cold in +Chicago. The climate of the whole world would have been different, and +you can see how animals and men would have been forced to move from one +place to another in search of food and warmth. + +On the other hand, it looks as if only a minor proportion of the whole +Ice Age was really taken up by times of glaciation. In between came +the _interglacial_ periods. During these times the climate around +Chicago was as warm as it is now, and sometimes even warmer. It may +interest you to know that the last great glacier melted away less than +10,000 years ago. Professor Ernst Antevs thinks we may be living in an +interglacial period and that the Ice Age may not be over yet. So if you +want to make a killing in real estate for your several hundred times +great-grandchildren, you might buy some land in the Arizona desert or +the Sahara. + +We do not yet know just why the glaciers appeared and disappeared, as +they did. It surely had something to do with an increase in rainfall +and a fall in temperature. It probably also had to do with a general +tendency for the land to rise at the beginning of the Pleistocene. We +know there was some mountain-building at that time. Hence, rain-bearing +winds nourished the rising and cooler uplands with snow. An increase +in all three of these factors--if they came together--would only have +needed to be slight. But exactly why this happened we do not know. + +The reason I tell you about the glaciers is simply to remind you of the +changing world in which prehistoric men lived. Their surroundings--the +animals and plants they used for food, and the weather they had to +protect themselves from--were always changing. On the other hand, this +change happened over so long a period of time and was so slow that +individual people could not have noticed it. Glaciers, about which they +probably knew nothing, moved in hundreds of miles to the north of them. +The people must simply have wandered ever more southward in search +of the plants and animals on which they lived. Or some men may have +stayed where they were and learned to hunt different animals and eat +different foods. Prehistoric men had to keep adapting themselves to new +environments and those who were most adaptive were most successful. + + +OTHER CHANGES + +Changes took place in the men themselves as well as in the ways they +lived. As time went on, they made better tools and weapons. Then, too, +we begin to find signs of how they started thinking of other things +than food and the tools to get it with. We find that they painted on +the walls of caves, and decorated their tools; we find that they buried +their dead. + +At about the time when the last great glacier was finally melting away, +men in the Near East made the first basic change in human economy. +They began to plant grain, and they learned to raise and herd certain +animals. This meant that they could store food in granaries and “on the +hoof” against the bad times of the year. This first really basic change +in man’s way of living has been called the “food-producing revolution.” +By the time it happened, a modern kind of climate was beginning. Men +had already grown to look as they do now. Know-how in ways of living +had developed and progressed, slowly but surely, up to a point. It was +impossible for men to go beyond that point if they only hunted and +fished and gathered wild foods. Once the basic change was made--once +the food-producing revolution became effective--technology leaped ahead +and civilization and written history soon began. + + + + +Prehistoric Men THEMSELVES + +[Illustration] + + +DO WE KNOW WHERE MAN ORIGINATED? + +For a long time some scientists thought the “cradle of mankind” was in +central Asia. Other scientists insisted it was in Africa, and still +others said it might have been in Europe. Actually, we don’t know +where it was. We don’t even know that there was only _one_ “cradle.” +If we had to choose a “cradle” at this moment, we would probably say +Africa. But the southern portions of Asia and Europe may also have been +included in the general area. The scene of the early development of +mankind was certainly the Old World. It is pretty certain men didn’t +reach North or South America until almost the end of the Ice Age--had +they done so earlier we would certainly have found some trace of them +by now. + +The earliest tools we have yet found come from central and south +Africa. By the dating system I’m using, these tools must be over +500,000 years old. There are now reports that a few such early tools +have been found--at the Sterkfontein cave in South Africa--along with +the bones of small fossil men called “australopithecines.” + +Not all scientists would agree that the australopithecines were “men,” +or would agree that the tools were made by the australopithecines +themselves. For these sticklers, the earliest bones of men come from +the island of Java. The date would be about 450,000 years ago. So far, +we have not yet found the tools which we suppose these earliest men in +the Far East must have made. + +Let me say it another way. How old are the earliest traces of men we +now have? Over half a million years. This was a time when the first +alpine glaciation was happening in the north. What has been found so +far? The tools which the men of those times made, in different parts +of Africa. It is now fairly generally agreed that the “men” who made +the tools were the australopithecines. There is also a more “man-like” +jawbone at Kanam in Kenya, but its find-spot has been questioned. The +next earliest bones we have were found in Java, and they may be almost +a hundred thousand years younger than the earliest African finds. We +haven’t yet found the tools of these early Javanese. Our knowledge of +tool-using in Africa spreads quickly as time goes on: soon after the +appearance of tools in the south we shall have them from as far north +as Algeria. + +Very soon after the earliest Javanese come the bones of slightly more +developed people in Java, and the jawbone of a man who once lived in +what is now Germany. The same general glacial beds which yielded the +later Javanese bones and the German jawbone also include tools. These +finds come from the time of the second alpine glaciation. + +So this is the situation. By the time of the end of the second alpine +or first continental glaciation (say 400,000 years ago) we have traces +of men from the extremes of the more southerly portions of the Old +World--South Africa, eastern Asia, and western Europe. There are also +some traces of men in the middle ground. In fact, Professor Franz +Weidenreich believed that creatures who were the immediate ancestors +of men had already spread over Europe, Africa, and Asia by the time +the Ice Age began. We certainly have no reason to disbelieve this, but +fortunate accidents of discovery have not yet given us the evidence to +prove it. + + +MEN AND APES + +Many people used to get extremely upset at the ill-formed notion +that “man descended from the apes.” Such words were much more likely +to start fights or “monkey trials” than the correct notion that all +living animals, including man, ascended or evolved from a single-celled +organism which lived in the primeval seas hundreds of millions of years +ago. Men are mammals, of the order called Primates, and man’s living +relatives are the great apes. Men didn’t “descend” from the apes or +apes from men, and mankind must have had much closer relatives who have +since become extinct. + +Men stand erect. They also walk and run on their two feet. Apes are +happiest in trees, swinging with their arms from branch to branch. +Few branches of trees will hold the mighty gorilla, although he still +manages to sleep in trees. Apes can’t stand really erect in our sense, +and when they have to run on the ground, they use the knuckles of their +hands as well as their feet. + +A key group of fossil bones here are the south African +australopithecines. These are called the _Australopithecinae_ or +“man-apes” or sometimes even “ape-men.” We do not _know_ that they were +directly ancestral to men but they can hardly have been so to apes. +Presently I’ll describe them a bit more. The reason I mention them +here is that while they had brains no larger than those of apes, their +hipbones were enough like ours so that they must have stood erect. +There is no good reason to think they couldn’t have walked as we do. + + +BRAINS, HANDS, AND TOOLS + +Whether the australopithecines were our ancestors or not, the proper +ancestors of men must have been able to stand erect and to walk on +their two feet. Three further important things probably were involved, +next, before they could become men proper. These are: + + 1. The increasing size and development of the brain. + + 2. The increasing usefulness (specialization) of the thumb and hand. + + 3. The use of tools. + +Nobody knows which of these three is most important, or which came +first. Most probably the growth of all three things was very much +blended together. If you think about each of the things, you will see +what I mean. Unless your hand is more flexible than a paw, and your +thumb will work against (or oppose) your fingers, you can’t hold a tool +very well. But you wouldn’t get the idea of using a tool unless you had +enough brain to help you see cause and effect. And it is rather hard to +see how your hand and brain would develop unless they had something to +practice on--like using tools. In Professor Krogman’s words, “the hand +must become the obedient servant of the eye and the brain.” It is the +_co-ordination_ of these things that counts. + +Many other things must have been happening to the bodies of the +creatures who were the ancestors of men. Our ancestors had to develop +organs of speech. More than that, they had to get the idea of letting +_certain sounds_ made with these speech organs have _certain meanings_. + +All this must have gone very slowly. Probably everything was developing +little by little, all together. Men became men very slowly. + + +WHEN SHALL WE CALL MEN MEN? + +What do I mean when I say “men”? People who looked pretty much as we +do, and who used different tools to do different things, are men to me. +We’ll probably never know whether the earliest ones talked or not. They +probably had vocal cords, so they could make sounds, but did they know +how to make sounds work as symbols to carry meanings? But if the fossil +bones look like our skeletons, and if we find tools which we’ll agree +couldn’t have been made by nature or by animals, then I’d say we had +traces of _men_. + +The australopithecine finds of the Transvaal and Bechuanaland, in +south Africa, are bound to come into the discussion here. I’ve already +told you that the australopithecines could have stood upright and +walked on their two hind legs. They come from the very base of the +Pleistocene or Ice Age, and a few coarse stone tools have been found +with the australopithecine fossils. But there are three varieties +of the australopithecines and they last on until a time equal to +that of the second alpine glaciation. They are the best suggestion +we have yet as to what the ancestors of men _may_ have looked like. +They were certainly closer to men than to apes. Although their brain +size was no larger than the brains of modern apes their body size and +stature were quite small; hence, relative to their small size, their +brains were large. We have not been able to prove without doubt that +the australopithecines were _tool-making_ creatures, even though the +recent news has it that tools have been found with australopithecine +bones. The doubt as to whether the australopithecines used the tools +themselves goes like this--just suppose some man-like creature (whose +bones we have not yet found) made the tools and used them to kill +and butcher australopithecines. Hence a few experts tend to let +australopithecines still hang in limbo as “man-apes.” + + +THE EARLIEST MEN WE KNOW + +I’ll postpone talking about the tools of early men until the next +chapter. The men whose bones were the earliest of the Java lot have +been given the name _Meganthropus_. The bones are very fragmentary. We +would not understand them very well unless we had the somewhat later +Javanese lot--the more commonly known _Pithecanthropus_ or “Java +man”--against which to refer them for study. One of the less well-known +and earliest fragments, a piece of lower jaw and some teeth, rather +strongly resembles the lower jaws and teeth of the australopithecine +type. Was _Meganthropus_ a sort of half-way point between the +australopithecines and _Pithecanthropus_? It is still too early to say. +We shall need more finds before we can be definite one way or the other. + +Java man, _Pithecanthropus_, comes from geological beds equal in age +to the latter part of the second alpine glaciation; the _Meganthropus_ +finds refer to beds of the beginning of this glaciation. The first +finds of Java man were made in 1891-92 by Dr. Eugene Dubois, a Dutch +doctor in the colonial service. Finds have continued to be made. There +are now bones enough to account for four skulls. There are also four +jaws and some odd teeth and thigh bones. Java man, generally speaking, +was about five feet six inches tall, and didn’t hold his head very +erect. His skull was very thick and heavy and had room for little more +than two-thirds as large a brain as we have. He had big teeth and a big +jaw and enormous eyebrow ridges. + +No tools were found in the geological deposits where bones of Java man +appeared. There are some tools in the same general area, but they come +a bit later in time. One reason we accept the Java man as man--aside +from his general anatomical appearance--is that these tools probably +belonged to his near descendants. + +Remember that there are several varieties of men in the whole early +Java lot, at least two of which are earlier than the _Pithecanthropus_, +“Java man.” Some of the earlier ones seem to have gone in for +bigness, in tooth-size at least. _Meganthropus_ is one of these +earlier varieties. As we said, he _may_ turn out to be a link to +the australopithecines, who _may_ or _may not_ be ancestral to men. +_Meganthropus_ is best understandable in terms of _Pithecanthropus_, +who appeared later in the same general area. _Pithecanthropus_ is +pretty well understandable from the bones he left us, and also because +of his strong resemblance to the fully tool-using cave-dwelling “Peking +man,” _Sinanthropus_, about whom we shall talk next. But you can see +that the physical anthropologists and prehistoric archeologists still +have a lot of work to do on the problem of earliest men. + + +PEKING MEN AND SOME EARLY WESTERNERS + +The earliest known Chinese are called _Sinanthropus_, or “Peking man,” +because the finds were made near that city. In World War II, the United +States Marine guard at our Embassy in Peking tried to help get the +bones out of the city before the Japanese attack. Nobody knows where +these bones are now. The Red Chinese accuse us of having stolen them. +They were last seen on a dock-side at a Chinese port. But should you +catch a Marine with a sack of old bones, perhaps we could achieve peace +in Asia by returning them! Fortunately, there is a complete set of +casts of the bones. + +Peking man lived in a cave in a limestone hill, made tools, cracked +animal bones to get the marrow out, and used fire. Incidentally, the +bones of Peking man were found because Chinese dig for what they call +“dragon bones” and “dragon teeth.” Uneducated Chinese buy these things +in their drug stores and grind them into powder for medicine. The +“dragon teeth” and “bones” are really fossils of ancient animals, and +sometimes of men. The people who supply the drug stores have learned +where to dig for strange bones and teeth. Paleontologists who get to +China go to the drug stores to buy fossils. In a roundabout way, this +is how the fallen-in cave of Peking man at Choukoutien was discovered. + +Peking man was not quite as tall as Java man but he probably stood +straighter. His skull looked very much like that of the Java skull +except that it had room for a slightly larger brain. His face was less +brutish than was Java man’s face, but this isn’t saying much. + +Peking man dates from early in the interglacial period following the +second alpine glaciation. He probably lived close to 350,000 years +ago. There are several finds to account for in Europe by about this +time, and one from northwest Africa. The very large jawbone found +near Heidelberg in Germany is doubtless even earlier than Peking man. +The beds where it was found are of second alpine glacial times, and +recently some tools have been said to have come from the same beds. +There is not much I need tell you about the Heidelberg jaw save that it +seems certainly to have belonged to an early man, and that it is very +big. + +Another find in Germany was made at Steinheim. It consists of the +fragmentary skull of a man. It is very important because of its +relative completeness, but it has not yet been fully studied. The bone +is thick, but the back of the head is neither very low nor primitive, +and the face is also not primitive. The forehead does, however, have +big ridges over the eyes. The more fragmentary skull from Swanscombe in +England (p. 11) has been much more carefully studied. Only the top and +back of that skull have been found. Since the skull rounds up nicely, +it has been assumed that the face and forehead must have been quite +“modern.” Careful comparison with Steinheim shows that this was not +necessarily so. This is important because it bears on the question of +how early truly “modern” man appeared. + +Recently two fragmentary jaws were found at Ternafine in Algeria, +northwest Africa. They look like the jaws of Peking man. Tools were +found with them. Since no jaws have yet been found at Steinheim or +Swanscombe, but the time is the same, one wonders if these people had +jaws like those of Ternafine. + + +WHAT HAPPENED TO JAVA AND PEKING MEN + +Professor Weidenreich thought that there were at least a dozen ways in +which the Peking man resembled the modern Mongoloids. This would seem +to indicate that Peking man was really just a very early Chinese. + +Several later fossil men have been found in the Java-Australian area. +The best known of these is the so-called Solo man. There are some finds +from Australia itself which we now know to be quite late. But it looks +as if we may assume a line of evolution from Java man down to the +modern Australian natives. During parts of the Ice Age there was a land +bridge all the way from Java to Australia. + + +TWO ENGLISHMEN WHO WEREN’T OLD + +The older textbooks contain descriptions of two English finds which +were thought to be very old. These were called Piltdown (_Eoanthropus +dawsoni_) and Galley Hill. The skulls were very modern in appearance. +In 1948-49, British scientists began making chemical tests which proved +that neither of these finds is very old. It is now known that both +“Piltdown man” and the tools which were said to have been found with +him were part of an elaborate fake! + + +TYPICAL “CAVE MEN” + +The next men we have to talk about are all members of a related group. +These are the Neanderthal group. “Neanderthal man” himself was found in +the Neander Valley, near Düsseldorf, Germany, in 1856. He was the first +human fossil to be recognized as such. + +[Illustration: PRINCIPAL KNOWN TYPES OF FOSSIL MEN + + CRO-MAGNON + NEANDERTHAL + MODERN SKULL + COMBE-CAPELLE + SINANTHROPUS + PITHECANTHROPUS] + +Some of us think that the neanderthaloids proper are only those people +of western Europe who didn’t get out before the beginning of the last +great glaciation, and who found themselves hemmed in by the glaciers +in the Alps and northern Europe. Being hemmed in, they intermarried +a bit too much and developed into a special type. Professor F. Clark +Howell sees it this way. In Europe, the earliest trace of men we +now know is the Heidelberg jaw. Evolution continued in Europe, from +Heidelberg through the Swanscombe and Steinheim types to a group of +pre-neanderthaloids. There are traces of these pre-neanderthaloids +pretty much throughout Europe during the third interglacial period--say +100,000 years ago. The pre-neanderthaloids are represented by such +finds as the ones at Ehringsdorf in Germany and Saccopastore in Italy. +I won’t describe them for you, since they are simply less extreme than +the neanderthaloids proper--about half way between Steinheim and the +classic Neanderthal people. + +Professor Howell believes that the pre-neanderthaloids who happened to +get caught in the pocket of the southwest corner of Europe at the onset +of the last great glaciation became the classic Neanderthalers. Out in +the Near East, Howell thinks, it is possible to see traces of people +evolving from the pre-neanderthaloid type toward that of fully modern +man. Certainly, we don’t see such extreme cases of “neanderthaloidism” +outside of western Europe. + +There are at least a dozen good examples in the main or classic +Neanderthal group in Europe. They date to just before and in the +earlier part of the last great glaciation (85,000 to 40,000 years ago). +Many of the finds have been made in caves. The “cave men” the movies +and the cartoonists show you are probably meant to be Neanderthalers. +I’m not at all sure they dragged their women by the hair; the women +were probably pretty tough, too! + +Neanderthal men had large bony heads, but plenty of room for brains. +Some had brain cases even larger than the average for modern man. Their +faces were heavy, and they had eyebrow ridges of bone, but the ridges +were not as big as those of Java man. Their foreheads were very low, +and they didn’t have much chin. They were about five feet three inches +tall, but were heavy and barrel-chested. But the Neanderthalers didn’t +slouch as much as they’ve been blamed for, either. + +One important thing about the Neanderthal group is that there is a fair +number of them to study. Just as important is the fact that we know +something about how they lived, and about some of the tools they made. + + +OTHER MEN CONTEMPORARY WITH THE NEANDERTHALOIDS + +We have seen that the neanderthaloids seem to be a specialization +in a corner of Europe. What was going on elsewhere? We think that +the pre-neanderthaloid type was a generally widespread form of men. +From this type evolved other more or less extreme although generally +related men. The Solo finds in Java form one such case. Another was the +Rhodesian man of Africa, and the more recent Hopefield finds show more +of the general Rhodesian type. It is more confusing than it needs to be +if these cases outside western Europe are called neanderthaloids. They +lived during the same approximate time range but they were all somewhat +different-looking people. + + +EARLY MODERN MEN + +How early is modern man (_Homo sapiens_), the “wise man”? Some people +have thought that he was very early, a few still think so. Piltdown +and Galley Hill, which were quite modern in anatomical appearance and +_supposedly_ very early in date, were the best “evidence” for very +early modern men. Now that Piltdown has been liquidated and Galley Hill +is known to be very late, what is left of the idea? + +The backs of the skulls of the Swanscombe and Steinheim finds look +rather modern. Unless you pay attention to the face and forehead of the +Steinheim find--which not many people have--and perhaps also consider +the Ternafine jaws, you might come to the conclusion that the crown of +the Swanscombe head was that of a modern-like man. + +Two more skulls, again without faces, are available from a French +cave site, Fontéchevade. They come from the time of the last great +interglacial, as did the pre-neanderthaloids. The crowns of the +Fontéchevade skulls also look quite modern. There is a bit of the +forehead preserved on one of these skulls and the brow-ridge is not +heavy. Nevertheless, there is a suggestion that the bones belonged to +an immature individual. In this case, his (or even more so, if _her_) +brow-ridges would have been weak anyway. The case for the Fontéchevade +fossils, as modern type men, is little stronger than that for +Swanscombe, although Professor Vallois believes it a good case. + +It seems to add up to the fact that there were people living in +Europe--before the classic neanderthaloids--who looked more modern, +in some features, than the classic western neanderthaloids did. Our +best suggestion of what men looked like--just before they became fully +modern--comes from a cave on Mount Carmel in Palestine. + + +THE FIRST MODERNS + +Professor T. D. McCown and the late Sir Arthur Keith, who studied the +Mount Carmel bones, figured out that one of the two groups involved +was as much as 70 per cent modern. There were, in fact, two groups or +varieties of men in the Mount Carmel caves and in at least two other +Palestinian caves of about the same time. The time would be about that +of the onset of colder weather, when the last glaciation was beginning +in the north--say 75,000 years ago. + +The 70 per cent modern group came from only one cave, Mugharet es-Skhul +(“cave of the kids”). The other group, from several caves, had bones of +men of the type we’ve been calling pre-neanderthaloid which we noted +were widespread in Europe and beyond. The tools which came with each +of these finds were generally similar, and McCown and Keith, and other +scholars since their study, have tended to assume that both the Skhul +group and the pre-neanderthaloid group came from exactly the same time. +The conclusion was quite natural: here was a population of men in the +act of evolving in two different directions. But the time may not be +exactly the same. It is very difficult to be precise, within say 10,000 +years, for a time some 75,000 years ago. If the Skhul men are in fact +later than the pre-neanderthaloid group of Palestine, as some of us +think, then they show how relatively modern some men were--men who +lived at the same time as the classic Neanderthalers of the European +pocket. + +Soon after the first extremely cold phase of the last glaciation, we +begin to get a number of bones of completely modern men in Europe. +We also get great numbers of the tools they made, and their living +places in caves. Completely modern skeletons begin turning up in caves +dating back to toward 40,000 years ago. The time is about that of the +beginning of the second phase of the last glaciation. These skeletons +belonged to people no different from many people we see today. Like +people today, not everybody looked alike. (The positions of the more +important fossil men of later Europe are shown in the chart on page +72.) + + +DIFFERENCES IN THE EARLY MODERNS + +The main early European moderns have been divided into two groups, the +Cro-Magnon group and the Combe Capelle-Brünn group. Cro-Magnon people +were tall and big-boned, with large, long, and rugged heads. They +must have been built like many present-day Scandinavians. The Combe +Capelle-Brünn people were shorter; they had narrow heads and faces, and +big eyebrow-ridges. Of course we don’t find the skin or hair of these +people. But there is little doubt they were Caucasoids (“Whites”). + +Another important find came in the Italian Riviera, near Monte Carlo. +Here, in a cave near Grimaldi, there was a grave containing a woman +and a young boy, buried together. The two skeletons were first called +“Negroid” because some features of their bones were thought to resemble +certain features of modern African Negro bones. But more recently, +Professor E. A. Hooton and other experts questioned the use of the word +“Negroid” in describing the Grimaldi skeletons. It is true that nothing +is known of the skin color, hair form, or any other fleshy feature of +the Grimaldi people, so that the word “Negroid” in its usual meaning is +not proper here. It is also not clear whether the features of the bones +claimed to be “Negroid” are really so at all. + +From a place called Wadjak, in Java, we have “proto-Australoid” skulls +which closely resemble those of modern Australian natives. Some of +the skulls found in South Africa, especially the Boskop skull, look +like those of modern Bushmen, but are much bigger. The ancestors of +the Bushmen seem to have once been very widespread south of the Sahara +Desert. True African Negroes were forest people who apparently expanded +out of the west central African area only in the last several thousand +years. Although dark in skin color, neither the Australians nor the +Bushmen are Negroes; neither the Wadjak nor the Boskop skulls are +“Negroid.” + +As we’ve already mentioned, Professor Weidenreich believed that Peking +man was already on the way to becoming a Mongoloid. Anyway, the +Mongoloids would seem to have been present by the time of the “Upper +Cave” at Choukoutien, the _Sinanthropus_ find-spot. + + +WHAT THE DIFFERENCES MEAN + +What does all this difference mean? It means that, at one moment in +time, within each different area, men tended to look somewhat alike. +From area to area, men tended to look somewhat different, just as +they do today. This is all quite natural. People _tended_ to mate +near home; in the anthropological jargon, they made up geographically +localized breeding populations. The simple continental division of +“stocks”--black = Africa, yellow = Asia, white = Europe--is too simple +a picture to fit the facts. People became accustomed to life in some +particular area within a continent (we might call it a “natural area”). +As they went on living there, they evolved towards some particular +physical variety. It would, of course, have been difficult to draw +a clear boundary between two adjacent areas. There must always have +been some mating across the boundaries in every case. One thing human +beings don’t do, and never have done, is to mate for “purity.” It is +self-righteous nonsense when we try to kid ourselves into thinking that +they do. + +I am not going to struggle with the whole business of modern stocks and +races. This is a book about prehistoric men, not recent historic or +modern men. My physical anthropologist friends have been very patient +in helping me to write and rewrite this chapter--I am not going to +break their patience completely. Races are their business, not mine, +and they must do the writing about races. I shall, however, give two +modern definitions of race, and then make one comment. + + Dr. William G. Boyd, professor of Immunochemistry, School of + Medicine, Boston University: “We may define a human race as a + population which differs significantly from other human populations + in regard to the frequency of one or more of the genes it + possesses.” + + Professor Sherwood L. Washburn, professor of Physical Anthropology, + Department of Anthropology, the University of California: “A ‘race’ + is a group of genetically similar populations, and races intergrade + because there are always intermediate populations.” + +My comment is that the ideas involved here are all biological: they +concern groups, _not_ individuals. Boyd and Washburn may differ a bit +on what they want to consider a “population,” but a population is a +group nevertheless, and genetics is biology to the hilt. Now a lot of +people still think of race in terms of how people dress or fix their +food or of other habits or customs they have. The next step is to talk +about racial “purity.” None of this has anything whatever to do with +race proper, which is a matter of the biology of groups. + +Incidentally, I’m told that if man very carefully _controls_ +the breeding of certain animals over generations--dogs, cattle, +chickens--he might achieve a “pure” race of animals. But he doesn’t do +it. Some unfortunate genetic trait soon turns up, so this has just as +carefully to be bred out again, and so on. + + +SUMMARY OF PRESENT KNOWLEDGE OF FOSSIL MEN + +The earliest bones of men we now have--upon which all the experts +would probably agree--are those of _Meganthropus_, from Java, of about +450,000 years ago. The earlier australopithecines of Africa were +possibly not tool-users and may not have been ancestral to men at all. +But there is an alternate and evidently increasingly stronger chance +that some of them may have been. The Kanam jaw from Kenya, another +early possibility, is not only very incomplete but its find-spot is +very questionable. + +Java man proper, _Pithecanthropus_, comes next, at about 400,000 years +ago, and the big Heidelberg jaw in Germany must be of about the same +date. Next comes Swanscombe in England, Steinheim in Germany, the +Ternafine jaws in Algeria, and Peking man, _Sinanthropus_. They all +date to the second great interglacial period, about 350,000 years ago. + +Piltdown and Galley Hill are out, and with them, much of the starch +in the old idea that there were two distinct lines of development +in human evolution: (1) a line of “paleoanthropic” development from +Heidelberg to the Neanderthalers where it became extinct, and (2) a +very early “modern” line, through Piltdown, Galley Hill, Swanscombe, to +us. Swanscombe, Steinheim, and Ternafine are just as easily cases of +very early pre-neanderthaloids. + +The pre-neanderthaloids were very widespread during the third +interglacial: Ehringsdorf, Saccopastore, some of the Mount Carmel +people, and probably Fontéchevade are cases in point. A variety of +their descendants can be seen, from Java (Solo), Africa (Rhodesian +man), and about the Mediterranean and in western Europe. As the acute +cold of the last glaciation set in, the western Europeans found +themselves surrounded by water, ice, or bitter cold tundra. To vastly +over-simplify it, they “bred in” and became classic neanderthaloids. +But on Mount Carmel, the Skhul cave-find with its 70 per cent modern +features shows what could happen elsewhere at the same time. + +Lastly, from about 40,000 or 35,000 years ago--the time of the onset +of the second phase of the last glaciation--we begin to find the fully +modern skeletons of men. The modern skeletons differ from place to +place, just as different groups of men living in different places still +look different. + +What became of the Neanderthalers? Nobody can tell me for sure. I’ve a +hunch they were simply “bred out” again when the cold weather was over. +Many Americans, as the years go by, are no longer ashamed to claim they +have “Indian blood in their veins.” Give us a few more generations +and there will not be very many other Americans left to whom we can +brag about it. It certainly isn’t inconceivable to me to imagine a +little Cro-Magnon boy bragging to his friends about his tough, strong, +Neanderthaler great-great-great-great-grandfather! + + + + +Cultural BEGINNINGS + +[Illustration] + + +Men, unlike the lower animals, are made up of much more than flesh and +blood and bones; for men have “culture.” + + +WHAT IS CULTURE? + +“Culture” is a word with many meanings. The doctors speak of making a +“culture” of a certain kind of bacteria, and ants are said to have a +“culture.” Then there is the Emily Post kind of “culture”--you say a +person is “cultured,” or that he isn’t, depending on such things as +whether or not he eats peas with his knife. + +The anthropologists use the word too, and argue heatedly over its finer +meanings; but they all agree that every human being is part of or has +some kind of culture. Each particular human group has a particular +culture; that is one of the ways in which we can tell one group of +men from another. In this sense, a CULTURE means the way the members +of a group of people think and believe and live, the tools they make, +and the way they do things. Professor Robert Redfield says a culture +is an organized or formalized body of conventional understandings. +“Conventional understandings” means the whole set of rules, beliefs, +and standards which a group of people lives by. These understandings +show themselves in art, and in the other things a people may make and +do. The understandings continue to last, through tradition, from one +generation to another. They are what really characterize different +human groups. + + +SOME CHARACTERISTICS OF CULTURE + +A culture lasts, although individual men in the group die off. On +the other hand, a culture changes as the different conventions and +understandings change. You could almost say that a culture lives in the +minds of the men who have it. But people are not born with it; they +get it as they grow up. Suppose a day-old Hungarian baby is adopted by +a family in Oshkosh, Wisconsin, and the child is not told that he is +Hungarian. He will grow up with no more idea of Hungarian culture than +anyone else in Oshkosh. + +So when I speak of ancient Egyptian culture, I mean the whole body +of understandings and beliefs and knowledge possessed by the ancient +Egyptians. I mean their beliefs as to why grain grew, as well as their +ability to make tools with which to reap the grain. I mean their +beliefs about life after death. What I am thinking about as culture is +a thing which lasted in time. If any one Egyptian, even the Pharaoh, +died, it didn’t affect the Egyptian culture of that particular moment. + + +PREHISTORIC CULTURES + +For that long period of man’s history that is all prehistory, we have +no written descriptions of cultures. We find only the tools men made, +the places where they lived, the graves in which they buried their +dead. Fortunately for us, these tools and living places and graves all +tell us something about the ways these men lived and the things they +believed. But the story we learn of the very early cultures must be +only a very small part of the whole, for we find so few things. The +rest of the story is gone forever. We have to do what we can with what +we find. + +For all of the time up to about 75,000 years ago, which was the time +of the classic European Neanderthal group of men, we have found few +cave-dwelling places of very early prehistoric men. First, there is the +fallen-in cave where Peking man was found, near Peking. Then there are +two or three other _early_, but not _very early_, possibilities. The +finds at the base of the French cave of Fontéchevade, those in one of +the Makapan caves in South Africa, and several open sites such as Dr. +L. S. B. Leakey’s Olorgesailie in Kenya doubtless all lie earlier than +the time of the main European Neanderthal group, but none are so early +as the Peking finds. + +You can see that we know very little about the home life of earlier +prehistoric men. We find different kinds of early stone tools, but we +can’t even be really sure which tools may have been used together. + + +WHY LITTLE HAS LASTED FROM EARLY TIMES + +Except for the rare find-spots mentioned above, all our very early +finds come from geological deposits, or from the wind-blown surfaces +of deserts. Here is what the business of geological deposits really +means. Let us say that a group of people was living in England about +300,000 years ago. They made the tools they needed, lived in some sort +of camp, almost certainly built fires, and perhaps buried their dead. +While the climate was still warm, many generations may have lived in +the same place, hunting, and gathering nuts and berries; but after some +few thousand years, the weather began very gradually to grow colder. +These early Englishmen would not have known that a glacier was forming +over northern Europe. They would only have noticed that the animals +they hunted seemed to be moving south, and that the berries grew larger +toward the south. So they would have moved south, too. + +The camp site they left is the place we archeologists would really have +liked to find. All of the different tools the people used would have +been there together--many broken, some whole. The graves, and traces +of fire, and the tools would have been there. But the glacier got +there first! The front of this enormous sheet of ice moved down over +the country, crushing and breaking and plowing up everything, like a +gigantic bulldozer. You can see what happened to our camp site. + +Everything the glacier couldn’t break, it pushed along in front of it +or plowed beneath it. Rocks were ground to gravel, and soil was caught +into the ice, which afterwards melted and ran off as muddy water. Hard +tools of flint sometimes remained whole. Human bones weren’t so hard; +it’s a wonder _any_ of them lasted. Gushing streams of melt water +flushed out the debris from underneath the glacier, and water flowed +off the surface and through great crevasses. The hard materials these +waters carried were even more rolled and ground up. Finally, such +materials were dropped by the rushing waters as gravels, miles from +the front of the glacier. At last the glacier reached its greatest +extent; then it melted backward toward the north. Debris held in the +ice was dropped where the ice melted, or was flushed off by more melt +water. When the glacier, leaving the land, had withdrawn to the sea, +great hunks of ice were broken off as icebergs. These icebergs probably +dropped the materials held in their ice wherever they floated and +melted. There must be many tools and fragmentary bones of prehistoric +men on the bottom of the Atlantic Ocean and the North Sea. + +Remember, too, that these glaciers came and went at least three or four +times during the Ice Age. Then you will realize why the earlier things +we find are all mixed up. Stone tools from one camp site got mixed up +with stone tools from many other camp sites--tools which may have been +made tens of thousands or more years apart. The glaciers mixed them +all up, and so we cannot say which particular sets of tools belonged +together in the first place. + + +“EOLITHS” + +But what sort of tools do we find earliest? For almost a century, +people have been picking up odd bits of flint and other stone in the +oldest Ice Age gravels in England and France. It is now thought these +odd bits of stone weren’t actually worked by prehistoric men. The +stones were given a name, _eoliths_, or “dawn stones.” You can see them +in many museums; but you can be pretty sure that very few of them were +actually fashioned by men. + +It is impossible to pick out “eoliths” that seem to be made in any +one _tradition_. By “tradition” I mean a set of habits for making one +kind of tool for some particular job. No two “eoliths” look very much +alike: tools made as part of some one tradition all look much alike. +Now it’s easy to suppose that the very earliest prehistoric men picked +up and used almost any sort of stone. This wouldn’t be surprising; you +and I do it when we go camping. In other words, some of these “eoliths” +may actually have been used by prehistoric men. They must have used +anything that might be handy when they needed it. We could have figured +that out without the “eoliths.” + + +THE ROAD TO STANDARDIZATION + +Reasoning from what we know or can easily imagine, there should have +been three major steps in the prehistory of tool-making. The first step +would have been simple _utilization_ of what was at hand. This is the +step into which the “eoliths” would fall. The second step would have +been _fashioning_--the haphazard preparation of a tool when there was a +need for it. Probably many of the earlier pebble tools, which I shall +describe next, fall into this group. The third step would have been +_standardization_. Here, men began to make tools according to certain +set traditions. Counting the better-made pebble tools, there are four +such traditions or sets of habits for the production of stone tools in +earliest prehistoric times. Toward the end of the Pleistocene, a fifth +tradition appears. + + +PEBBLE TOOLS + +At the beginning of the last chapter, you’ll remember that I said there +were tools from very early geological beds. The earliest bones of men +have not yet been found in such early beds although the Sterkfontein +australopithecine cave approaches this early date. The earliest tools +come from Africa. They date back to the time of the first great +alpine glaciation and are at least 500,000 years old. The earliest +ones are made of split pebbles, about the size of your fist or a bit +bigger. They go under the name of pebble tools. There are many natural +exposures of early Pleistocene geological beds in Africa, and the +prehistoric archeologists of south and central Africa have concentrated +on searching for early tools. Other finds of early pebble tools have +recently been made in Algeria and Morocco. + +[Illustration: SOUTH AFRICAN PEBBLE TOOL] + +There are probably early pebble tools to be found in areas of the +Old World besides Africa; in fact, some prehistorians already claim +to have identified a few. Since the forms and the distinct ways of +making the earlier pebble tools had not yet sufficiently jelled into +a set tradition, they are difficult for us to recognize. It is not +so difficult, however, if there are great numbers of “possibles” +available. A little later in time the tradition becomes more clearly +set, and pebble tools are easier to recognize. So far, really large +collections of pebble tools have only been found and examined in Africa. + + +CORE-BIFACE TOOLS + +The next tradition we’ll look at is the _core_ or biface one. The tools +are large pear-shaped pieces of stone trimmed flat on the two opposite +sides or “faces.” Hence “biface” has been used to describe these tools. +The front view is like that of a pear with a rather pointed top, and +the back view looks almost exactly the same. Look at them side on, and +you can see that the front and back faces are the same and have been +trimmed to a thin tip. The real purpose in trimming down the two faces +was to get a good cutting edge all around. You can see all this in the +illustration. + +[Illustration: ABBEVILLIAN BIFACE] + +We have very little idea of the way in which these core-bifaces were +used. They have been called “hand axes,” but this probably gives the +wrong idea, for an ax, to us, is not a pointed tool. All of these early +tools must have been used for a number of jobs--chopping, scraping, +cutting, hitting, picking, and prying. Since the core-bifaces tend to +be pointed, it seems likely that they were used for hitting, picking, +and prying. But they have rough cutting edges, so they could have been +used for chopping, scraping, and cutting. + + +FLAKE TOOLS + +The third tradition is the _flake_ tradition. The idea was to get a +tool with a good cutting edge by simply knocking a nice large flake off +a big block of stone. You had to break off the flake in such a way that +it was broad and thin, and also had a good sharp cutting edge. Once you +really got on to the trick of doing it, this was probably a simpler way +to make a good cutting tool than preparing a biface. You have to know +how, though; I’ve tried it and have mashed my fingers more than once. + +The flake tools look as if they were meant mainly for chopping, +scraping, and cutting jobs. When one made a flake tool, the idea seems +to have been to produce a broad, sharp, cutting edge. + +[Illustration: CLACTONIAN FLAKE] + +The core-biface and the flake traditions were spread, from earliest +times, over much of Europe, Africa, and western Asia. The map on page +52 shows the general area. Over much of this great region there was +flint. Both of these traditions seem well adapted to flint, although +good core-bifaces and flakes were made from other kinds of stone, +especially in Africa south of the Sahara. + + +CHOPPERS AND ADZE-LIKE TOOLS + +The fourth early tradition is found in southern and eastern Asia, from +northwestern India through Java and Burma into China. Father Maringer +recently reported an early group of tools in Japan, which most resemble +those of Java, called Patjitanian. The prehistoric men in this general +area mostly used quartz and tuff and even petrified wood for their +stone tools (see illustration, p. 46). + +This fourth early tradition is called the _chopper-chopping tool_ +tradition. It probably has its earliest roots in the pebble tool +tradition of African type. There are several kinds of tools in this +tradition, but all differ from the western core-bifaces and flakes. +There are broad, heavy scrapers or cleavers, and tools with an +adze-like cutting edge. These last-named tools are called “hand adzes,” +just as the core-bifaces of the west have often been called “hand +axes.” The section of an adze cutting edge is ? shaped; the section of +an ax is < shaped. + +[Illustration: ANYATHIAN ADZE-LIKE TOOL] + +There are also pointed pebble tools. Thus the tool kit of these early +south and east Asiatic peoples seems to have included tools for doing +as many different jobs as did the tools of the Western traditions. + +Dr. H. L. Movius has emphasized that the tools which were found in the +Peking cave with Peking man belong to the chopper-tool tradition. This +is the only case as yet where the tools and the man have been found +together from very earliest times--if we except Sterkfontein. + + +DIFFERENCES WITHIN THE TOOL-MAKING TRADITIONS + +The latter three great traditions in the manufacture of stone +tools--and the less clear-cut pebble tools before them--are all we have +to show of the cultures of the men of those times. Changes happened in +each of the traditions. As time went on, the tools in each tradition +were better made. There could also be slight regional differences in +the tools within one tradition. Thus, tools with small differences, but +all belonging to one tradition, can be given special group (facies) +names. + +This naming of special groups has been going on for some time. Here are +some of these names, since you may see them used in museum displays +of flint tools, or in books. Within each tradition of tool-making +(save the chopper tools), the earliest tool type is at the bottom +of the list, just as it appears in the lowest beds of a geological +stratification.[3] + + [3] Archeologists usually make their charts and lists with the + earliest materials at the bottom and the latest on top, since + this is the way they find them in the ground. + + Chopper tool (all about equally early): + Anyathian (Burma) + Choukoutienian (China) + Patjitanian (Java) + Soan (India) + + Flake: + “Typical Mousterian” + Levalloiso-Mousterian + Levalloisian + Tayacian + Clactonian (localized in England) + + Core-biface: + Some blended elements in “Mousterian” + Micoquian (= Acheulean 6 and 7) + Acheulean + Abbevillian (once called “Chellean”) + + Pebble tool: + Oldowan + Ain Hanech + pre-Stellenbosch + Kafuan + +The core-biface and the flake traditions appear in the chart (p. 65). + +The early archeologists had many of the tool groups named before they +ever realized that there were broader tool preparation traditions. This +was understandable, for in dealing with the mixture of things that come +out of glacial gravels the easiest thing to do first is to isolate +individual types of tools into groups. First you put a bushel-basketful +of tools on a table and begin matching up types. Then you give names to +the groups of each type. The groups and the types are really matters of +the archeologists’ choice; in real life, they were probably less exact +than the archeologists’ lists of them. We now know pretty well in which +of the early traditions the various early groups belong. + + +THE MEANING OF THE DIFFERENT TRADITIONS + +What do the traditions really mean? I see them as the standardization +of ways to make tools for particular jobs. We may not know exactly what +job the maker of a particular core-biface or flake tool had in mind. We +can easily see, however, that he already enjoyed a know-how, a set of +persistent habits of tool preparation, which would always give him the +same type of tool when he wanted to make it. Therefore, the traditions +show us that persistent habits already existed for the preparation of +one type of tool or another. + +This tells us that one of the characteristic aspects of human culture +was already present. There must have been, in the minds of these +early men, a notion of the ideal type of tool for a particular job. +Furthermore, since we find so many thousands upon thousands of tools +of one type or another, the notion of the ideal types of tools _and_ +the know-how for the making of each type must have been held in common +by many men. The notions of the ideal types and the know-how for their +production must have been passed on from one generation to another. + +I could even guess that the notions of the ideal type of one or the +other of these tools stood out in the minds of men of those times +somewhat like a symbol of “perfect tool for good job.” If this were +so--remember it’s only a wild guess of mine--then men were already +symbol users. Now let’s go on a further step to the fact that the words +men speak are simply sounds, each different sound being a symbol for a +different meaning. If standardized tool-making suggests symbol-making, +is it also possible that crude word-symbols were also being made? I +suppose that it is not impossible. + +There may, of course, be a real question whether tool-utilizing +creatures--our first step, on page 42--were actually men. Other +animals utilize things at hand as tools. The tool-fashioning creature +of our second step is more suggestive, although we may not yet feel +sure that many of the earlier pebble tools were man-made products. But +with the step to standardization and the appearance of the traditions, +I believe we must surely be dealing with the traces of culture-bearing +_men_. The “conventional understandings” which Professor Redfield’s +definition of culture suggests are now evidenced for us in the +persistent habits for the preparation of stone tools. Were we able to +see the other things these prehistoric men must have made--in materials +no longer preserved for the archeologist to find--I believe there would +be clear signs of further conventional understandings. The men may have +been physically primitive and pretty shaggy in appearance, but I think +we must surely call them men. + + +AN OLDER INTERPRETATION OF THE WESTERN TRADITIONS + +In the last chapter, I told you that many of the older archeologists +and human paleontologists used to think that modern man was very old. +The supposed ages of Piltdown and Galley Hill were given as evidence +of the great age of anatomically modern man, and some interpretations +of the Swanscombe and Fontéchevade fossils were taken to support +this view. The conclusion was that there were two parallel lines or +“phyla” of men already present well back in the Pleistocene. The +first of these, the more primitive or “paleoanthropic” line, was +said to include Heidelberg, the proto-neanderthaloids and classic +Neanderthal. The more anatomically modern or “neanthropic” line was +thought to consist of Piltdown and the others mentioned above. The +Neanderthaler or paleoanthropic line was thought to have become extinct +after the first phase of the last great glaciation. Of course, the +modern or neanthropic line was believed to have persisted into the +present, as the basis for the world’s population today. But with +Piltdown liquidated, Galley Hill known to be very late, and Swanscombe +and Fontéchevade otherwise interpreted, there is little left of the +so-called parallel phyla theory. + +While the theory was in vogue, however, and as long as the European +archeological evidence was looked at in one short-sighted way, the +archeological materials _seemed_ to fit the parallel phyla theory. It +was simply necessary to believe that the flake tools were made only +by the paleoanthropic Neanderthaler line, and that the more handsome +core-biface tools were the product of the neanthropic modern-man line. + +Remember that _almost_ all of the early prehistoric European tools +came only from the redeposited gravel beds. This means that the tools +were not normally found in the remains of camp sites or work shops +where they had actually been dropped by the men who made and used +them. The tools came, rather, from the secondary hodge-podge of the +glacial gravels. I tried to give you a picture of the bulldozing action +of glaciers (p. 40) and of the erosion and weathering that were +side-effects of a glacially conditioned climate on the earth’s surface. +As we said above, if one simply plucks tools out of the redeposited +gravels, his natural tendency is to “type” the tools by groups, and to +think that the groups stand for something _on their own_. + +In 1906, M. Victor Commont actually made a rare find of what seems +to have been a kind of workshop site, on a terrace above the Somme +river in France. Here, Commont realized, flake tools appeared clearly +in direct association with core-biface tools. Few prehistorians paid +attention to Commont or his site, however. It was easier to believe +that flake tools represented a distinct “culture” and that this +“culture” was that of the Neanderthaler or paleoanthropic line, and +that the core-bifaces stood for another “culture” which was that of the +supposed early modern or neanthropic line. Of course, I am obviously +skipping many details here. Some later sites with Neanderthal fossils +do seem to have only flake tools, but other such sites have both types +of tools. The flake tools which appeared _with_ the core-bifaces +in the Swanscombe gravels were never made much of, although it +was embarrassing for the parallel phyla people that Fontéchevade +ran heavily to flake tools. All in all, the parallel phyla theory +flourished because it seemed so neat and easy to understand. + + +TRADITIONS ARE TOOL-MAKING HABITS, NOT CULTURES + +In case you think I simply enjoy beating a dead horse, look in any +standard book on prehistory written twenty (or even ten) years ago, or +in most encyclopedias. You’ll find that each of the individual tool +types, of the West, at least, was supposed to represent a “culture.” +The “cultures” were believed to correspond to parallel lines of human +evolution. + +In 1937, Mr. Harper Kelley strongly re-emphasized the importance +of Commont’s workshop site and the presence of flake tools with +core-bifaces. Next followed Dr. Movius’ clear delineation of the +chopper-chopping tool tradition of the Far East. This spoiled the nice +symmetry of the flake-tool = paleoanthropic, core-biface = neanthropic +equations. Then came increasing understanding of the importance of +the pebble tools in Africa, and the location of several more workshop +sites there, especially at Olorgesailie in Kenya. Finally came the +liquidation of Piltdown and the deflation of Galley Hill’s date. So it +is at last possible to picture an individual prehistoric man making a +flake tool to do one job and a core-biface tool to do another. Commont +showed us this picture in 1906, but few believed him. + +[Illustration: DISTRIBUTION OF TOOL-PREPARATION TRADITIONS + +Time approximately 100,000 years ago] + +There are certainly a few cases in which flake tools did appear with +few or no core-bifaces. The flake-tool group called Clactonian in +England is such a case. Another good, but certainly later case is +that of the cave on Mount Carmel in Palestine, where the blended +pre-neanderthaloid, 70 per cent modern-type skulls were found. Here, in +the same level with the skulls, were 9,784 flint tools. Of these, only +three--doubtless strays--were core-bifaces; all the rest were flake +tools or flake chips. We noted above how the Fontéchevade cave ran to +flake tools. The only conclusion I would draw from this is that times +and circumstances did exist in which prehistoric men needed only flake +tools. So they only made flake tools for those particular times and +circumstances. + + +LIFE IN EARLIEST TIMES + +What do we actually know of life in these earliest times? In the +glacial gravels, or in the terrace gravels of rivers once swollen by +floods of melt water or heavy rains, or on the windswept deserts, we +find stone tools. The earliest and coarsest of these are the pebble +tools. We do not yet know what the men who made them looked like, +although the Sterkfontein australopithecines probably give us a good +hint. Then begin the more formal tool preparation traditions of the +west--the core-bifaces and the flake tools--and the chopper-chopping +tool series of the farther east. There is an occasional roughly worked +piece of bone. From the gravels which yield the Clactonian flakes of +England comes the fire-hardened point of a wooden spear. There are +also the chance finds of the fossil human bones themselves, of which +we spoke in the last chapter. Aside from the cave of Peking man, none +of the earliest tools have been found in caves. Open air or “workshop” +sites which do not seem to have been disturbed later by some geological +agency are very rare. + +The chart on page 65 shows graphically what the situation in +west-central Europe seems to have been. It is not yet certain whether +there were pebble tools there or not. The Fontéchevade cave comes +into the picture about 100,000 years ago or more. But for the earlier +hundreds of thousands of years--below the red-dotted line on the +chart--the tools we find come almost entirely from the haphazard +mixture within the geological contexts. + +The stone tools of each of the earlier traditions are the simplest +kinds of all-purpose tools. Almost any one of them could be used for +hacking, chopping, cutting, and scraping; so the men who used them must +have been living in a rough and ready sort of way. They found or hunted +their food wherever they could. In the anthropological jargon, they +were “food-gatherers,” pure and simple. + +Because of the mixture in the gravels and in the materials they +carried, we can’t be sure which animals these men hunted. Bones of +the larger animals turn up in the gravels, but they could just as +well belong to the animals who hunted the men, rather than the other +way about. We don’t know. This is why camp sites like Commont’s and +Olorgesailie in Kenya are so important when we do find them. The animal +bones at Olorgesailie belonged to various mammals of extremely large +size. Probably they were taken in pit-traps, but there are a number of +groups of three round stones on the site which suggest that the people +used bolas. The South American Indians used three-ball bolas, with the +stones in separate leather bags connected by thongs. These were whirled +and then thrown through the air so as to entangle the feet of a fleeing +animal. + +Professor F. Clark Howell recently returned from excavating another +important open air site at Isimila in Tanganyika. The site yielded +the bones of many fossil animals and also thousands of core-bifaces, +flakes, and choppers. But Howell’s reconstruction of the food-getting +habits of the Isimila people certainly suggests that the word “hunting” +is too dignified for what they did; “scavenging” would be much nearer +the mark. + +During a great part of this time the climate was warm and pleasant. The +second interglacial period (the time between the second and third great +alpine glaciations) lasted a long time, and during much of this time +the climate may have been even better than ours is now. We don’t know +that earlier prehistoric men in Europe or Africa lived in caves. They +may not have needed to; much of the weather may have been so nice that +they lived in the open. Perhaps they didn’t wear clothes, either. + + +WHAT THE PEKING CAVE-FINDS TELL US + +The one early cave-dwelling we have found is that of Peking man, in +China. Peking man had fire. He probably cooked his meat, or used +the fire to keep dangerous animals away from his den. In the cave +were bones of dangerous animals, members of the wolf, bear, and cat +families. Some of the cat bones belonged to beasts larger than tigers. +There were also bones of other wild animals: buffalo, camel, deer, +elephants, horses, sheep, and even ostriches. Seventy per cent of the +animals Peking man killed were fallow deer. It’s much too cold and dry +in north China for all these animals to live there today. So this list +helps us know that the weather was reasonably warm, and that there was +enough rain to grow grass for the grazing animals. The list also helps +the paleontologists to date the find. + +Peking man also seems to have eaten plant food, for there are hackberry +seeds in the debris of the cave. His tools were made of sandstone and +quartz and sometimes of a rather bad flint. As we’ve already seen, they +belong in the chopper-tool tradition. It seems fairly clear that some +of the edges were chipped by right-handed people. There are also many +split pieces of heavy bone. Peking man probably split them so he could +eat the bone marrow, but he may have used some of them as tools. + +Many of these split bones were the bones of Peking men. Each one of the +skulls had already had the base broken out of it. In no case were any +of the bones resting together in their natural relation to one another. +There is nothing like a burial; all of the bones are scattered. Now +it’s true that animals could have scattered bodies that were not cared +for or buried. But splitting bones lengthwise and carefully removing +the base of a skull call for both the tools and the people to use them. +It’s pretty clear who the people were. Peking man was a cannibal. + + * * * * * + +This rounds out about all we can say of the life and times of early +prehistoric men. In those days life was rough. You evidently had to +watch out not only for dangerous animals but also for your fellow men. +You ate whatever you could catch or find growing. But you had sense +enough to build fires, and you had already formed certain habits for +making the kinds of stone tools you needed. That’s about all we know. +But I think we’ll have to admit that cultural beginnings had been made, +and that these early people were really _men_. + + + + +MORE EVIDENCE of Culture + +[Illustration] + + +While the dating is not yet sure, the material that we get from caves +in Europe must go back to about 100,000 years ago; the time of the +classic Neanderthal group followed soon afterwards. We don’t know why +there is no earlier material in the caves; apparently they were not +used before the last interglacial phase (the period just before the +last great glaciation). We know that men of the classic Neanderthal +group were living in caves from about 75,000 to 45,000 years ago. +New radioactive carbon dates even suggest that some of the traces of +culture we’ll describe in this chapter may have lasted to about 35,000 +years ago. Probably some of the pre-neanderthaloid types of men had +also lived in caves. But we have so far found their bones in caves only +in Palestine and at Fontéchevade. + + +THE CAVE LAYERS + +In parts of France, some peasants still live in caves. In prehistoric +time, many generations of people lived in them. As a result, many +caves have deep layers of debris. The first people moved in and lived +on the rock floor. They threw on the floor whatever they didn’t want, +and they tracked in mud; nobody bothered to clean house in those days. +Their debris--junk and mud and garbage and what not--became packed +into a layer. As time went on, and generations passed, the layer grew +thicker. Then there might have been a break in the occupation of the +cave for a while. Perhaps the game animals got scarce and the people +moved away; or maybe the cave became flooded. Later on, other people +moved in and began making a new layer of their own on top of the first +layer. Perhaps this process of layering went on in the same cave for a +hundred thousand years; you can see what happened. The drawing on this +page shows a section through such a cave. The earliest layer is on the +bottom, the latest one on top. They go in order from bottom to top, +earliest to latest. This is the _stratification_ we talked about (p. +12). + +[Illustration: SECTION OF SHELTER ON LOWER TERRACE, LE MOUSTIER] + +While we may find a mix-up in caves, it’s not nearly as bad as the +mixing up that was done by glaciers. The animal bones and shells, the +fireplaces, the bones of men, and the tools the men made all belong +together, if they come from one layer. That’s the reason why the cave +of Peking man is so important. It is also the reason why the caves in +Europe and the Near East are so important. We can get an idea of which +things belong together and which lot came earliest and which latest. + +In most cases, prehistoric men lived only in the mouths of caves. +They didn’t like the dark inner chambers as places to live in. They +preferred rock-shelters, at the bases of overhanging cliffs, if there +was enough overhang to give shelter. When the weather was good, they no +doubt lived in the open air as well. I’ll go on using the term “cave” +since it’s more familiar, but remember that I really mean rock-shelter, +as a place in which people actually lived. + +The most important European cave sites are in Spain, France, and +central Europe; there are also sites in England and Italy. A few caves +are known in the Near East and Africa, and no doubt more sites will be +found when the out-of-the-way parts of Europe, Africa, and Asia are +studied. + + +AN “INDUSTRY” DEFINED + +We have already seen that the earliest European cave materials are +those from the cave of Fontéchevade. Movius feels certain that the +lowest materials here date back well into the third interglacial stage, +that which lay between the Riss (next to the last) and the Würm I +(first stage of the last) alpine glaciations. This material consists +of an _industry_ of stone tools, apparently all made in the flake +tradition. This is the first time we have used the word “industry.” +It is useful to call all of the different tools found together in one +layer and made of _one kind of material_ an industry; that is, the +tools must be found together as men left them. Tools taken from the +glacial gravels (or from windswept desert surfaces or river gravels +or any geological deposit) are not “together” in this sense. We might +say the latter have only “geological,” not “archeological” context. +Archeological context means finding things just as men left them. We +can tell what tools go together in an “industrial” sense only if we +have archeological context. + +Up to now, the only things we could have called “industries” were the +worked stone industry and perhaps the worked (?) bone industry of the +Peking cave. We could add some of the very clear cases of open air +sites, like Olorgesailie. We couldn’t use the term for the stone tools +from the glacial gravels, because we do not know which tools belonged +together. But when the cave materials begin to appear in Europe, we can +begin to speak of industries. Most of the European caves of this time +contain industries of flint tools alone. + + +THE EARLIEST EUROPEAN CAVE LAYERS + +We’ve just mentioned the industry from what is said to be the oldest +inhabited cave in Europe; that is, the industry from the deepest layer +of the site at Fontéchevade. Apparently it doesn’t amount to much. The +tools are made of stone, in the flake tradition, and are very poorly +worked. This industry is called _Tayacian_. Its type tool seems to be +a smallish flake tool, but there are also larger flakes which seem to +have been fashioned for hacking. In fact, the type tool seems to be +simply a smaller edition of the Clactonian tool (pictured on p. 45). + +None of the Fontéchevade tools are really good. There are scrapers, +and more or less pointed tools, and tools that may have been used +for hacking and chopping. Many of the tools from the earlier glacial +gravels are better made than those of this first industry we see in +a European cave. There is so little of this material available that +we do not know which is really typical and which is not. You would +probably find it hard to see much difference between this industry and +a collection of tools of the type called Clactonian, taken from the +glacial gravels, especially if the Clactonian tools were small-sized. + +The stone industry of the bottommost layer of the Mount Carmel cave, +in Palestine, where somewhat similar tools were found, has also been +called Tayacian. + +I shall have to bring in many unfamiliar words for the names of the +industries. The industries are usually named after the places where +they were first found, and since these were in most cases in France, +most of the names which follow will be of French origin. However, +the names have simply become handles and are in use far beyond the +boundaries of France. It would be better if we had a non-place-name +terminology, but archeologists have not yet been able to agree on such +a terminology. + + +THE ACHEULEAN INDUSTRY + +Both in France and in Palestine, as well as in some African cave +sites, the next layers in the deep caves have an industry in both the +core-biface and the flake traditions. The core-biface tools usually +make up less than half of all the tools in the industry. However, +the name of the biface type of tool is generally given to the whole +industry. It is called the _Acheulean_, actually a late form of it, as +“Acheulean” is also used for earlier core-biface tools taken from the +glacial gravels. In western Europe, the name used is _Upper Acheulean_ +or _Micoquian_. The same terms have been borrowed to name layers E and +F in the Tabun cave, on Mount Carmel in Palestine. + +The Acheulean core-biface type of tool is worked on two faces so as +to give a cutting edge all around. The outline of its front view may +be oval, or egg-shaped, or a quite pointed pear shape. The large +chip-scars of the Acheulean core-bifaces are shallow and flat. It is +suspected that this resulted from the removal of the chips with a +wooden club; the deep chip-scars of the earlier Abbevillian core-biface +came from beating the tool against a stone anvil. These tools are +really the best and also the final products of the core-biface +tradition. We first noticed the tradition in the early glacial gravels +(p. 43); now we see its end, but also its finest examples, in the +deeper cave levels. + +The flake tools, which really make up the greater bulk of this +industry, are simple scrapers and chips with sharp cutting edges. The +habits used to prepare them must have been pretty much the same as +those used for at least one of the flake industries we shall mention +presently. + +There is very little else in these early cave layers. We do not have +a proper “industry” of bone tools. There are traces of fire, and of +animal bones, and a few shells. In Palestine, there are many more +bones of deer than of gazelle in these layers; the deer lives in a +wetter climate than does the gazelle. In the European cave layers, the +animal bones are those of beasts that live in a warm climate. They +belonged in the last interglacial period. We have not yet found the +bones of fossil men definitely in place with this industry. + +[Illustration: ACHEULEAN BIFACE] + + +FLAKE INDUSTRIES FROM THE CAVES + +Two more stone industries--the _Levalloisian_ and the +“_Mousterian_”--turn up at approximately the same time in the European +cave layers. Their tools seem to be mainly in the flake tradition, +but according to some of the authorities their preparation also shows +some combination with the habits by which the core-biface tools were +prepared. + +Now notice that I don’t tell you the Levalloisian and the “Mousterian” +layers are both above the late Acheulean layers. Look at the cave +section (p. 57) and you’ll find that some “Mousterian of Acheulean +tradition” appears above some “typical Mousterian.” This means that +there may be some kinds of Acheulean industries that are later than +some kinds of “Mousterian.” The same is true of the Levalloisian. + +There were now several different kinds of habits that men used in +making stone tools. These habits were based on either one or the other +of the two traditions--core-biface or flake--or on combinations of +the habits used in the preparation techniques of both traditions. All +were popular at about the same time. So we find that people who made +one kind of stone tool industry lived in a cave for a while. Then they +gave up the cave for some reason, and people with another industry +moved in. Then the first people came back--or at least somebody with +the same tool-making habits as the first people. Or maybe a third group +of tool-makers moved in. The people who had these different habits for +making their stone tools seem to have moved around a good deal. They no +doubt borrowed and exchanged tricks of the trade with each other. There +were no patent laws in those days. + +The extremely complicated interrelationships of the different habits +used by the tool-makers of this range of time are at last being +systematically studied. M. François Bordes has developed a statistical +method of great importance for understanding these tool preparation +habits. + + +THE LEVALLOISIAN AND MOUSTERIAN + +The easiest Levalloisian tool to spot is a big flake tool. The trick +in making it was to fashion carefully a big chunk of stone (called +the Levalloisian “tortoise core,” because it resembles the shape of +a turtle-shell) and then to whack this in such a way that a large +flake flew off. This large thin flake, with sharp cutting edges, is +the finished Levalloisian tool. There were various other tools in a +Levalloisian industry, but this is the characteristic _Levalloisian_ +tool. + +There are several “typical Mousterian” stone tools. Different from +the tools of the Levalloisian type, these were made from “disc-like +cores.” There are medium-sized flake “side scrapers.” There are also +some small pointed tools and some small “hand axes.” The last of these +tool types is often a flake worked on both of the flat sides (that +is, bifacially). There are also pieces of flint worked into the form +of crude balls. The pointed tools may have been fixed on shafts to +make short jabbing spears; the round flint balls may have been used as +bolas. Actually, we don’t _know_ what either tool was used for. The +points and side scrapers are illustrated (pp. 64 and 66). + +[Illustration: LEVALLOIS FLAKE] + + +THE MIXING OF TRADITIONS + +Nowadays the archeologists are less and less sure of the importance +of any one specific tool type and name. Twenty years ago, they used +to speak simply of Acheulean or Levalloisian or Mousterian tools. +Now, more and more, _all_ of the tools from some one layer in a +cave are called an “industry,” which is given a mixed name. Thus we +have “Levalloiso-Mousterian,” and “Acheuleo-Levalloisian,” and even +“Acheuleo-Mousterian” (or “Mousterian of Acheulean tradition”). Bordes’ +systematic work is beginning to clear up some of our confusion. + +The time of these late Acheuleo-Levalloiso-Mousterioid industries +is from perhaps as early as 100,000 years ago. It may have lasted +until well past 50,000 years ago. This was the time of the first +phase of the last great glaciation. It was also the time that the +classic group of Neanderthal men was living in Europe. A number of +the Neanderthal fossil finds come from these cave layers. Before the +different habits of tool preparation were understood it used to be +popular to say Neanderthal man was “Mousterian man.” I think this is +wrong. What used to be called “Mousterian” is now known to be a variety +of industries with tools of both core-biface and flake habits, and +so mixed that the word “Mousterian” used alone really doesn’t mean +anything. The Neanderthalers doubtless understood the tool preparation +habits by means of which Acheulean, Levalloisian and Mousterian type +tools were produced. We also have the more modern-like Mount Carmel +people, found in a cave layer of Palestine with tools almost entirely +in the flake tradition, called “Levalloiso-Mousterian,” and the +Fontéchevade-Tayacian (p. 59). + +[Illustration: MOUSTERIAN POINT] + + +OTHER SUGGESTIONS OF LIFE IN THE EARLY CAVE LAYERS + +Except for the stone tools, what do we know of the way men lived in the +time range after 100,000 to perhaps 40,000 years ago or even later? +We know that in the area from Europe to Palestine, at least some of +the people (some of the time) lived in the fronts of caves and warmed +themselves over fires. In Europe, in the cave layers of these times, +we find the bones of different animals; the bones in the lowest layers +belong to animals that lived in a warm climate; above them are the +bones of those who could stand the cold, like the reindeer and mammoth. +Thus, the meat diet must have been changing, as the glacier crept +farther south. Shells and possibly fish bones have lasted in these +cave layers, but there is not a trace of the vegetable foods and the +nuts and berries and other wild fruits that must have been eaten when +they could be found. + +[Illustration: CHART SHOWING PRESENT UNDERSTANDING OF RELATIONSHIPS AND +SUCCESSION OF TOOL-PREPARATION TRADITIONS, INDUSTRIES, AND ASSEMBLAGES +OF WEST-CENTRAL EUROPE + +Wavy lines indicate transitions in industrial habits. These transitions +are not yet understood in detail. The glacial and climatic scheme shown +is the alpine one.] + +Bone tools have also been found from this period. Some are called +scrapers, and there are also long chisel-like leg-bone fragments +believed to have been used for skinning animals. Larger hunks of bone, +which seem to have served as anvils or chopping blocks, are fairly +common. + +Bits of mineral, used as coloring matter, have also been found. We +don’t know what the color was used for. + +[Illustration: MOUSTERIAN SIDE SCRAPER] + +There is a small but certain number of cases of intentional burials. +These burials have been found on the floors of the caves; in other +words, the people dug graves in the places where they lived. The holes +made for the graves were small. For this reason (or perhaps for some +other?) the bodies were in a curled-up or contracted position. Flint or +bone tools or pieces of meat seem to have been put in with some of the +bodies. In several cases, flat stones had been laid over the graves. + + +TOOLS FROM AFRICA AND ASIA ABOUT 100,000 YEARS AGO + +Professor Movius characterizes early prehistoric Africa as a continent +showing a variety of stone industries. Some of these industries were +purely local developments and some were practically identical with +industries found in Europe at the same time. From northwest Africa +to Capetown--excepting the tropical rain forest region of the west +center--tools of developed Acheulean, Levalloisian, and Mousterian +types have been recognized. Often they are named after African place +names. + +In east and south Africa lived people whose industries show a +development of the Levalloisian technique. Such industries are +called Stillbay. Another industry, developed on the basis of the +Acheulean technique, is called Fauresmith. From the northwest comes +an industry with tanged points and flake-blades; this is called the +Aterian. The tropical rain forest region contained people whose stone +tools apparently show adjustment to this peculiar environment; the +so-called Sangoan industry includes stone picks, adzes, core-bifaces +of specialized Acheulean type, and bifacial points which were probably +spearheads. + +In western Asia, even as far as the east coast of India, the tools of +the Eurafrican core-biface and flake tool traditions continued to be +used. But in the Far East, as we noted in the last chapter, men had +developed characteristic stone chopper and chopping tools. This tool +preparation tradition--basically a pebble tool tradition--lasted to the +very end of the Ice Age. + +When more intact open air sites such as that of an earlier time at +Olorgesailie, and more stratified cave sites are found and excavated +in Asia and Africa, we shall be able to get a more complete picture. +So far, our picture of the general cultural level of the Old World at +about 100,000 years ago--and soon afterwards--is best from Europe, but +it is still far from complete there, too. + + +CULTURE AT THE BEGINNING OF THE LAST GREAT GLACIAL PERIOD + +The few things we have found must indicate only a very small part +of the total activities of the people who lived at the time. All of +the things they made of wood and bark, of skins, of anything soft, +are gone. The fact that burials were made, at least in Europe and +Palestine, is pretty clear proof that the people had some notion of a +life after death. But what this notion really was, or what gods (if +any) men believed in, we cannot know. Dr. Movius has also reminded me +of the so-called bear cults--cases in which caves have been found which +contain the skulls of bears in apparently purposeful arrangement. This +might suggest some notion of hoarding up the spirits or the strength of +bears killed in the hunt. Probably the people lived in small groups, +as hunting and food-gathering seldom provide enough food for large +groups of people. These groups probably had some kind of leader or +“chief.” Very likely the rude beginnings of rules for community life +and politics, and even law, were being made. But what these were, we +do not know. We can only guess about such things, as we can only guess +about many others; for example, how the idea of a family must have been +growing, and how there may have been witch doctors who made beginnings +in medicine or in art, in the materials they gathered for their trade. + +The stone tools help us most. They have lasted, and we can find +them. As they come to us, from this cave or that, and from this +layer or that, the tool industries show a variety of combinations +of the different basic habits or traditions of tool preparation. +This seems only natural, as the groups of people must have been very +small. The mixtures and blendings of the habits used in making stone +tools must mean that there were also mixtures and blends in many of +the other ideas and beliefs of these small groups. And what this +probably means is that there was no one _culture_ of the time. It is +certainly unlikely that there were simply three cultures, “Acheulean,” +“Levalloisian,” and “Mousterian,” as has been thought in the past. +Rather there must have been a great variety of loosely related cultures +at about the same stage of advancement. We could say, too, that here +we really begin to see, for the first time, that remarkable ability +of men to adapt themselves to a variety of conditions. We shall see +this adaptive ability even more clearly as time goes on and the record +becomes more complete. + +Over how great an area did these loosely related cultures reach in +the time 75,000 to 45,000 or even as late as 35,000 years ago? We +have described stone tools made in one or another of the flake and +core-biface habits, for an enormous area. It covers all of Europe, all +of Africa, the Near East, and parts of India. It is perfectly possible +that the flake and core-biface habits lasted on after 35,000 years ago, +in some places outside of Europe. In northern Africa, for example, we +are certain that they did (see chart, p. 72). + +On the other hand, in the Far East (China, Burma, Java) and in northern +India, the tools of the old chopper-tool tradition were still being +made. Out there, we must assume, there was a different set of loosely +related cultures. At least, there was a different set of loosely +related habits for the making of tools. But the men who made them must +have looked much like the men of the West. Their tools were different, +but just as useful. + +As to what the men of the West looked like, I’ve already hinted at all +we know so far (pp. 29 ff.). The Neanderthalers were present at +the time. Some more modern-like men must have been about, too, since +fossils of them have turned up at Mount Carmel in Palestine, and at +Teshik Tash, in Trans-caspian Russia. It is still too soon to know +whether certain combinations of tools within industries were made +only by certain physical types of men. But since tools of both the +core-biface and the flake traditions, and their blends, turn up from +South Africa to England to India, it is most unlikely that only one +type of man used only one particular habit in the preparation of tools. +What seems perfectly clear is that men in Africa and men in India were +making just as good tools as the men who lived in western Europe. + + + + +EARLY MODERNS + +[Illustration] + + +From some time during the first inter-stadial of the last great +glaciation (say some time after about 40,000 years ago), we have +more accurate dates for the European-Mediterranean area and less +accurate ones for the rest of the Old World. This is probably +because the effects of the last glaciation have been studied in the +European-Mediterranean area more than they have been elsewhere. + + +A NEW TRADITION APPEARS + +Something new was probably beginning to happen in the +European-Mediterranean area about 40,000 years ago, though all the +rest of the Old World seems to have been going on as it had been. I +can’t be sure of this because the information we are using as a basis +for dates is very inaccurate for the areas outside of Europe and the +Mediterranean. + +We can at least make a guess. In Egypt and north Africa, men were still +using the old methods of making stone tools. This was especially true +of flake tools of the Levalloisian type, save that they were growing +smaller and smaller as time went on. But at the same time, a new +tradition was becoming popular in westernmost Asia and in Europe. This +was the blade-tool tradition. + + +BLADE TOOLS + +A stone blade is really just a long parallel-sided flake, as the +drawing shows. It has sharp cutting edges, and makes a very useful +knife. The real trick is to be able to make one. It is almost +impossible to make a blade out of any stone but flint or a natural +volcanic glass called obsidian. And even if you have flint or obsidian, +you first have to work up a special cone-shaped “blade-core,” from +which to whack off blades. + +[Illustration: PLAIN BLADE] + +You whack with a hammer stone against a bone or antler punch which is +directed at the proper place on the blade-core. The blade-core has to +be well supported or gripped while this is going on. To get a good +flint blade tool takes a great deal of know-how. + +Remember that a tradition in stone tools means no more than that some +particular way of making the tools got started and lasted a long time. +Men who made some tools in one tradition or set of habits would also +make other tools for different purposes by means of another tradition +or set of habits. It was even possible for the two sets of habits to +become combined. + + +THE EARLIEST BLADE TOOLS + +The oldest blade tools we have found were deep down in the layers of +the Mount Carmel caves, in Tabun Eb and Ea. Similar tools have been +found in equally early cave levels in Syria; their popularity there +seems to fluctuate a bit. Some more or less parallel-sided flakes are +known in the Levalloisian industry in France, but they are probably +no earlier than Tabun E. The Tabun blades are part of a local late +“Acheulean” industry, which is characterized by core-biface “hand +axes,” but which has many flake tools as well. Professor F. E. +Zeuner believes that this industry may be more than 120,000 years old; +actually its date has not yet been fixed, but it is very old--older +than the fossil finds of modern-like men in the same caves. + +[Illustration: SUCCESSION OF ICE AGE FLINT TYPES, INDUSTRIES, AND +ASSEMBLAGES, AND OF FOSSIL MEN, IN NORTHWESTERN EURAFRASIA] + +For some reason, the habit of making blades in Palestine and Syria was +interrupted. Blades only reappeared there at about the same time they +were first made in Europe, some time after 45,000 years ago; that is, +after the first phase of the last glaciation was ended. + +[Illustration: BACKED BLADE] + +We are not sure just where the earliest _persisting_ habits for the +production of blade tools developed. Impressed by the very early +momentary appearance of blades at Tabun on Mount Carmel, Professor +Dorothy A. Garrod first favored the Near East as a center of origin. +She spoke of “some as yet unidentified Asiatic centre,” which she +thought might be in the highlands of Iran or just beyond. But more +recent work has been done in this area, especially by Professor Coon, +and the blade tools do not seem to have an early appearance there. When +the blade tools reappear in the Syro-Palestinian area, they do so in +industries which also include Levalloiso-Mousterian flake tools. From +the point of view of form and workmanship, the blade tools themselves +are not so fine as those which seem to be making their appearance +in western Europe about the same time. There is a characteristic +Syro-Palestinian flake point, possibly a projectile tip, called the +Emiran, which is not known from Europe. The appearance of blade tools, +together with Levalloiso-Mousterian flakes, continues even after the +Emiran point has gone out of use. + +It seems clear that the production of blade tools did not immediately +swamp the set of older habits in Europe, too; the use of flake +tools also continued there. This was not so apparent to the older +archeologists, whose attention was focused on individual tool types. It +is not, in fact, impossible--although it is certainly not proved--that +the technique developed in the preparation of the Levalloisian tortoise +core (and the striking of the Levalloisian flake from it) might have +followed through to the conical core and punch technique for the +production of blades. Professor Garrod is much impressed with the speed +of change during the later phases of the last glaciation, and its +probable consequences. She speaks of “the greater number of industries +having enough individual character to be classified as distinct ... +since evolution now starts to outstrip diffusion.” Her “evolution” here +is of course an industrial evolution rather than a biological one. +Certainly the people of Europe had begun to make blade tools during +the warm spell after the first phase of the last glaciation. By about +40,000 years ago blades were well established. The bones of the blade +tool makers we’ve found so far indicate that anatomically modern men +had now certainly appeared. Unfortunately, only a few fossil men have +so far been found from the very beginning of the blade tool range in +Europe (or elsewhere). What I certainly shall _not_ tell you is that +conquering bands of fine, strong, anatomically modern men, armed with +superior blade tools, came sweeping out of the East to exterminate the +lowly Neanderthalers. Even if we don’t know exactly what happened, I’d +lay a good bet it wasn’t that simple. + +We do know a good deal about different blade industries in Europe. +Almost all of them come from cave layers. There is a great deal of +complication in what we find. The chart (p. 72) tries to simplify +this complication; in fact, it doubtless simplifies it too much. But +it may suggest all the complication of industries which is going +on at this time. You will note that the upper portion of my much +simpler chart (p. 65) covers the same material (in the section +marked “Various Blade-Tool Industries”). That chart is certainly too +simplified. + +You will realize that all this complication comes not only from +the fact that we are finding more material. It is due also to the +increasing ability of men to adapt themselves to a great variety of +situations. Their tools indicate this adaptiveness. We know there was +a good deal of climatic change at this time. The plants and animals +that men used for food were changing, too. The great variety of tools +and industries we now find reflect these changes and the ability of men +to keep up with the times. Now, for example, is the first time we are +sure that there are tools to _make_ other tools. They also show men’s +increasing ability to adapt themselves. + + +SPECIAL TYPES OF BLADE TOOLS + +The most useful tools that appear at this time were made from blades. + + 1. The “backed” blade. This is a knife made of a flint blade, with + one edge purposely blunted, probably to save the user’s fingers + from being cut. There are several shapes of backed blades (p. + 73). + + [Illustration: TWO BURINS] + + 2. The _burin_ or “graver.” The burin was the original chisel. Its + cutting edge is _transverse_, like a chisel’s. Some burins are + made like a screw-driver, save that burins are sharp. Others have + edges more like the blade of a chisel or a push plane, with + only one bevel. Burins were probably used to make slots in wood + and bone; that is, to make handles or shafts for other tools. + They must also be the tools with which much of the engraving on + bone (see p. 83) was done. There is a bewildering variety of + different kinds of burins. + +[Illustration: TANGED POINT] + + 3. The “tanged” point. These stone points were used to tip arrows or + light spears. They were made from blades, and they had a long tang + at the bottom where they were fixed to the shaft. At the place + where the tang met the main body of the stone point, there was + a marked “shoulder,” the beginnings of a barb. Such points had + either one or two shoulders. + +[Illustration: NOTCHED BLADE] + + 4. The “notched” or “strangulated” blade. Along with the points for + arrows or light spears must go a tool to prepare the arrow or + spear shaft. Today, such a tool would be called a “draw-knife” or + a “spoke-shave,” and this is what the notched blades probably are. + Our spoke-shaves have sharp straight cutting blades and really + “shave.” Notched blades of flint probably scraped rather than cut. + + 5. The “awl,” “drill,” or “borer.” These blade tools are worked out + to a spike-like point. They must have been used for making holes + in wood, bone, shell, skin, or other things. + +[Illustration: DRILL OR AWL] + + 6. The “end-scraper on a blade” is a tool with one or both ends + worked so as to give a good scraping edge. It could have been used + to hollow out wood or bone, scrape hides, remove bark from trees, + and a number of other things (p. 78). + +There is one very special type of flint tool, which is best known from +western Europe in an industry called the Solutrean. These tools were +usually made of blades, but the best examples are so carefully worked +on both sides (bifacially) that it is impossible to see the original +blade. This tool is + + 7. The “laurel leaf” point. Some of these tools were long and + dagger-like, and must have been used as knives or daggers. Others + were small, called “willow leaf,” and must have been mounted on + spear or arrow shafts. Another typical Solutrean tool is the + “shouldered” point. Both the “laurel leaf” and “shouldered” point + types are illustrated (see above and p. 79). + +[Illustration: END-SCRAPER ON A BLADE] + +[Illustration: LAUREL LEAF POINT] + +The industries characterized by tools in the blade tradition also +yield some flake and core tools. We will end this list with two types +of tools that appear at this time. The first is made of a flake; the +second is a core tool. + +[Illustration: SHOULDERED POINT] + + 8. The “keel-shaped round scraper” is usually small and quite round, + and has had chips removed up to a peak in the center. It is called + “keel-shaped” because it is supposed to look (when upside down) + like a section through a boat. Actually, it looks more like a tent + or an umbrella. Its outer edges are sharp all the way around, and + it was probably a general purpose scraping tool (see illustration, + p. 81). + + 9. The “keel-shaped nosed scraper” is a much larger and heavier tool + than the round scraper. It was made on a core with a flat bottom, + and has one nicely worked end or “nose.” Such tools are usually + large enough to be easily grasped, and probably were used like + push planes (see illustration, p. 81). + +[Illustration: KEEL-SHAPED ROUND SCRAPER] + +[Illustration: KEEL-SHAPED NOSED SCRAPER] + +The stone tools (usually made of flint) we have just listed are among +the most easily recognized blade tools, although they show differences +in detail at different times. There are also many other kinds. Not +all of these tools appear in any one industry at one time. Thus the +different industries shown in the chart (p. 72) each have only some +of the blade tools we’ve just listed, and also a few flake tools. Some +industries even have a few core tools. The particular types of blade +tools appearing in one cave layer or another, and the frequency of +appearance of the different types, tell which industry we have in each +layer. + + +OTHER KINDS OF TOOLS + +By this time in Europe--say from about 40,000 to about 10,000 years +ago--we begin to find other kinds of material too. Bone tools begin +to appear. There are knives, pins, needles with eyes, and little +double-pointed straight bars of bone that were probably fish-hooks. The +fish-line would have been fastened in the center of the bar; when the +fish swallowed the bait, the bar would have caught cross-wise in the +fish’s mouth. + +One quite special kind of bone tool is a long flat point for a light +spear. It has a deep notch cut up into the breadth of its base, and is +called a “split-based bone point” (p. 82). We know examples of bone +beads from these times, and of bone handles for flint tools. Pierced +teeth of some animals were worn as beads or pendants, but I am not sure +that elks’ teeth were worn this early. There are even spool-shaped +“buttons” or toggles. + +[Illustration: SPLIT-BASED BONE POINT] + +[Illustration: SPEAR-THROWER] + +[Illustration: BONE HARPOON] + +Antler came into use for tools, especially in central and western +Europe. We do not know the use of one particular antler tool that +has a large hole bored in one end. One suggestion is that it was +a thong-stropper used to strop or work up hide thongs (see +illustration, below); another suggestion is that it was an arrow-shaft +straightener. + +Another interesting tool, usually of antler, is the spear-thrower, +which is little more than a stick with a notch or hook on one end. +The hook fits into the butt end of the spear, and the length of the +spear-thrower allows you to put much more power into the throw (p. +82). It works on pretty much the same principle as the sling. + +Very fancy harpoons of antler were also made in the latter half of +the period in western Europe. These harpoons had barbs on one or both +sides and a base which would slip out of the shaft (p. 82). Some have +engraved decoration. + + +THE BEGINNING OF ART + +[Illustration: THONG-STROPPER] + +In western Europe, at least, the period saw the beginning of several +kinds of art work. It is handy to break the art down into two great +groups: the movable art, and the cave paintings and sculpture. The +movable art group includes the scratchings, engravings, and modeling +which decorate tools and weapons. Knives, stroppers, spear-throwers, +harpoons, and sometimes just plain fragments of bone or antler are +often carved. There is also a group of large flat pebbles which seem +almost to have served as sketch blocks. The surfaces of these various +objects may show animals, or rather abstract floral designs, or +geometric designs. + +[Illustration: “VENUS” FIGURINE FROM WILLENDORF] + +Some of the movable art is not done on tools. The most remarkable +examples of this class are little figures of women. These women seem to +be pregnant, and their most female characteristics are much emphasized. +It is thought that these “Venus” or “Mother-goddess” figurines may be +meant to show the great forces of nature--fertility and the birth of +life. + + +CAVE PAINTINGS + +In the paintings on walls and ceilings of caves we have some examples +that compare with the best art of any time. The subjects were usually +animals, the great cold-weather beasts of the end of the Ice Age: the +mammoth, the wooly rhinoceros, the bison, the reindeer, the wild horse, +the bear, the wild boar, and wild cattle. As in the movable art, there +are different styles in the cave art. The really great cave art is +pretty well restricted to southern France and Cantabrian (northwestern) +Spain. + +There are several interesting things about the “Franco-Cantabrian” cave +art. It was done deep down in the darkest and most dangerous parts of +the caves, although the men lived only in the openings of caves. If you +think what they must have had for lights--crude lamps of hollowed stone +have been found, which must have burned some kind of oil or grease, +with a matted hair or fiber wick--and of the animals that may have +lurked in the caves, you’ll understand the part about danger. Then, +too, we’re sure the pictures these people painted were not simply to be +looked at and admired, for they painted one picture right over other +pictures which had been done earlier. Clearly, it was the _act_ of +_painting_ that counted. The painter had to go way down into the most +mysterious depths of the earth and create an animal in paint. Possibly +he believed that by doing this he gained some sort of magic power over +the same kind of animal when he hunted it in the open air. It certainly +doesn’t look as if he cared very much about the picture he painted--as +a finished product to be admired--for he or somebody else soon went +down and painted another animal right over the one he had done. + +The cave art of the Franco-Cantabrian style is one of the great +artistic achievements of all time. The subjects drawn are almost always +the larger animals of the time: the bison, wild cattle and horses, the +wooly rhinoceros, the mammoth, the wild boar, and the bear. In some of +the best examples, the beasts are drawn in full color and the paintings +are remarkably alive and charged with energy. They come from the hands +of men who knew the great animals well--knew the feel of their fur, the +tremendous drive of their muscles, and the danger one faced when he +hunted them. + +Another artistic style has been found in eastern Spain. It includes +lively drawings, often of people hunting with bow and arrow. The East +Spanish art is found on open rock faces and in rock-shelters. It is +less spectacular and apparently more recent than the Franco-Cantabrian +cave art. + + +LIFE AT THE END OF THE ICE AGE IN EUROPE + +Life in these times was probably as good as a hunter could expect it +to be. Game and fish seem to have been plentiful; berries and wild +fruits probably were, too. From France to Russia, great pits or +piles of animal bones have been found. Some of this killing was done +as our Plains Indians killed the buffalo--by stampeding them over +steep river banks or cliffs. There were also good tools for hunting, +however. In western Europe, people lived in the openings of caves and +under overhanging rocks. On the great plains of eastern Europe, very +crude huts were being built, half underground. The first part of this +time must have been cold, for it was the middle and end phases of the +last great glaciation. Northern Europe from Scotland to Scandinavia, +northern Germany and Russia, and also the higher mountains to the +south, were certainly covered with ice. But people had fire, and the +needles and tools that were used for scraping hides must mean that they +wore clothing. + +It is clear that men were thinking of a great variety of things beside +the tools that helped them get food and shelter. Such burials as we +find have more grave-gifts than before. Beads and ornaments and often +flint, bone, or antler tools are included in the grave, and sometimes +the body is sprinkled with red ochre. Red is the color of blood, which +means life, and of fire, which means heat. Professor Childe wonders if +the red ochre was a pathetic attempt at magic--to give back to the body +the heat that had gone from it. But pathetic or not, it is sure proof +that these people were already moved by death as men still are moved by +it. + +Their art is another example of the direction the human mind was +taking. And when I say human, I mean it in the fullest sense, for this +is the time in which fully modern man has appeared. On page 34, we +spoke of the Cro-Magnon group and of the Combe Capelle-Brünn group of +Caucasoids and of the Grimaldi “Negroids,” who are no longer believed +to be Negroid. I doubt that any one of these groups produced most of +the achievements of the times. It’s not yet absolutely sure which +particular group produced the great cave art. The artists were almost +certainly a blend of several (no doubt already mixed) groups. The pair +of Grimaldians were buried in a grave with a sprinkling of red ochre, +and were provided with shell beads and ornaments and with some blade +tools of flint. Regardless of the different names once given them by +the human paleontologists, each of these groups seems to have shared +equally in the cultural achievements of the times, for all that the +archeologists can say. + + +MICROLITHS + +One peculiar set of tools seems to serve as a marker for the very last +phase of the Ice Age in southwestern Europe. This tool-making habit is +also found about the shore of the Mediterranean basin, and it moved +into northern Europe as the last glaciation pulled northward. People +began making blade tools of very small size. They learned how to chip +very slender and tiny blades from a prepared core. Then they made these +little blades into tiny triangles, half-moons (“lunates”), trapezoids, +and several other geometric forms. These little tools are called +“microliths.” They are so small that most of them must have been fixed +in handles or shafts. + +[Illustration: MICROLITHS + + BLADE FRAGMENT + BURIN + LUNATE + TRAPEZOID + SCALENE TRIANGLE + ARROWHEAD] + +We have found several examples of microliths mounted in shafts. In +northern Europe, where their use soon spread, the microlithic triangles +or lunates were set in rows down each side of a bone or wood point. +One corner of each little triangle stuck out, and the whole thing +made a fine barbed harpoon. In historic times in Egypt, geometric +trapezoidal microliths were still in use as arrowheads. They were +fastened--broad end out--on the end of an arrow shaft. It seems queer +to give an arrow a point shaped like a “T.” Actually, the little points +were very sharp, and must have pierced the hides of animals very +easily. We also think that the broader cutting edge of the point may +have caused more bleeding than a pointed arrowhead would. In hunting +fleet-footed animals like the gazelle, which might run for miles after +being shot with an arrow, it was an advantage to cause as much bleeding +as possible, for the animal would drop sooner. + +We are not really sure where the microliths were first invented. There +is some evidence that they appear early in the Near East. Their use +was very common in northwest Africa but this came later. The microlith +makers who reached south Russia and central Europe possibly moved up +out of the Near East. Or it may have been the other way around; we +simply don’t yet know. + +Remember that the microliths we are talking about here were made from +carefully prepared little blades, and are often geometric in outline. +Each microlithic industry proper was made up, in good part, of such +tiny blade tools. But there were also some normal-sized blade tools and +even some flake scrapers, in most microlithic industries. I emphasize +this bladelet and the geometric character of the microlithic industries +of the western Old World, since there has sometimes been confusion in +the matter. Sometimes small flake chips, utilized as minute pointed +tools, have been called “microliths.” They may be _microlithic_ in size +in terms of the general meaning of the word, but they do not seem to +belong to the sub-tradition of the blade tool preparation habits which +we have been discussing here. + + +LATER BLADE-TOOL INDUSTRIES OF THE NEAR EAST AND AFRICA + +The blade-tool industries of normal size we talked about earlier spread +from Europe to central Siberia. We noted that blade tools were made +in western Asia too, and early, although Professor Garrod is no longer +sure that the whole tradition originated in the Near East. If you look +again at my chart (p. 72) you will note that in western Asia I list +some of the names of the western European industries, but with the +qualification “-like” (for example, “Gravettian-like”). The western +Asiatic blade-tool industries do vaguely recall some aspects of those +of western Europe, but we would probably be better off if we used +completely local names for them. The “Emiran” of my chart is such an +example; its industry includes a long spike-like blade point which has +no western European counterpart. + +When we last spoke of Africa (p. 66), I told you that stone tools +there were continuing in the Levalloisian flake tradition, and were +becoming smaller. At some time during this process, two new tool +types appeared in northern Africa: one was the Aterian point with +a tang (p. 67), and the other was a sort of “laurel leaf” point, +called the “Sbaikian.” These two tool types were both produced from +flakes. The Sbaikian points, especially, are roughly similar to some +of the Solutrean points of Europe. It has been suggested that both the +Sbaikian and Aterian points may be seen on their way to France through +their appearance in the Spanish cave deposits of Parpallo, but there is +also a rival “pre-Solutrean” in central Europe. We still do not know +whether there was any contact between the makers of these north African +tools and the Solutrean tool-makers. What does seem clear is that the +blade-tool tradition itself arrived late in northern Africa. + + +NETHER AFRICA + +Blade tools and “laurel leaf” points and some other probably late +stone tool types also appear in central and southern Africa. There +are geometric microliths on bladelets and even some coarse pottery in +east Africa. There is as yet no good way of telling just where these +items belong in time; in broad geological terms they are “late.” +Some people have guessed that they are as early as similar European +and Near Eastern examples, but I doubt it. The makers of small-sized +Levalloisian flake tools occupied much of Africa until very late in +time. + + +THE FAR EAST + +India and the Far East still seem to be going their own way. In India, +some blade tools have been found. These are not well dated, save that +we believe they must be post-Pleistocene. In the Far East it looks as +if the old chopper-tool tradition was still continuing. For Burma, +Dr. Movius feels this is fairly certain; for China he feels even more +certain. Actually, we know very little about the Far East at about the +time of the last glaciation. This is a shame, too, as you will soon +agree. + + +THE NEW WORLD BECOMES INHABITED + +At some time toward the end of the last great glaciation--almost +certainly after 20,000 years ago--people began to move over Bering +Strait, from Asia into America. As you know, the American Indians have +been assumed to be basically Mongoloids. New studies of blood group +types make this somewhat uncertain, but there is no doubt that the +ancestors of the American Indians came from Asia. + +The stone-tool traditions of Europe, Africa, the Near and Middle East, +and central Siberia, did _not_ move into the New World. With only a +very few special or late exceptions, there are _no_ core-bifaces, +flakes, or blade tools of the Old World. Such things just haven’t been +found here. + +This is why I say it’s a shame we don’t know more of the end of the +chopper-tool tradition in the Far East. According to Weidenreich, +the Mongoloids were in the Far East long before the end of the last +glaciation. If the genetics of the blood group types do demand a +non-Mongoloid ancestry for the American Indians, who else may have been +in the Far East 25,000 years ago? We know a little about the habits +for making stone tools which these first people brought with them, +and these habits don’t conform with those of the western Old World. +We’d better keep our eyes open for whatever happened to the end of +the chopper-tool tradition in northern China; already there are hints +that it lasted late there. Also we should watch future excavations +in eastern Siberia. Perhaps we shall find the chopper-tool tradition +spreading up that far. + + +THE NEW ERA + +Perhaps it comes in part from the way I read the evidence and perhaps +in part it is only intuition, but I feel that the materials of this +chapter suggest a new era in the ways of life. Before about 40,000 +years ago, people simply “gathered” their food, wandering over large +areas to scavenge or to hunt in a simple sort of way. But here we +have seen them “settling-in” more, perhaps restricting themselves in +their wanderings and adapting themselves to a given locality in more +intensive ways. This intensification might be suggested by the word +“collecting.” The ways of life we described in the earlier chapters +were “food-gathering” ways, but now an era of “food-collecting” has +begun. We shall see further intensifications of it in the next chapter. + + + + +End and PRELUDE + +[Illustration] + + +Up to the end of the last glaciation, we prehistorians have a +relatively comfortable time schedule. The farther back we go the less +exact we can be about time and details. Elbow-room of five, ten, +even fifty or more thousands of years becomes available for us to +maneuver in as we work backward in time. But now our story has come +forward to the point where more exact methods of dating are at hand. +The radioactive carbon method reaches back into the span of the last +glaciation. There are other methods, developed by the geologists and +paleobotanists, which supplement and extend the usefulness of the +radioactive carbon dates. And, happily, as our means of being more +exact increases, our story grows more exciting. There are also more +details of culture for us to deal with, which add to the interest. + + +CHANGES AT THE END OF THE ICE AGE + +The last great glaciation of the Ice Age was a two-part affair, with a +sub-phase at the end of the second part. In Europe the last sub-phase +of this glaciation commenced somewhere around 15,000 years ago. Then +the glaciers began to melt back, for the last time. Remember that +Professor Antevs (p. 19) isn’t sure the Ice Age is over yet! This +melting sometimes went by fits and starts, and the weather wasn’t +always changing for the better; but there was at least one time when +European weather was even better than it is now. + +The melting back of the glaciers and the weather fluctuations caused +other changes, too. We know a fair amount about these changes in +Europe. In an earlier chapter, we said that the whole Ice Age was a +matter of continual change over long periods of time. As the last +glaciers began to melt back some interesting things happened to mankind. + +In Europe, along with the melting of the last glaciers, geography +itself was changing. Britain and Ireland had certainly become islands +by 5000 B.C. The Baltic was sometimes a salt sea, sometimes a large +fresh-water lake. Forests began to grow where the glaciers had been, +and in what had once been the cold tundra areas in front of the +glaciers. The great cold-weather animals--the mammoth and the wooly +rhinoceros--retreated northward and finally died out. It is probable +that the efficient hunting of the earlier people of 20,000 or 25,000 +to about 12,000 years ago had helped this process along (see p. 86). +Europeans, especially those of the post-glacial period, had to keep +changing to keep up with the times. + +The archeological materials for the time from 10,000 to 6000 B.C. seem +simpler than those of the previous five thousand years. The great cave +art of France and Spain had gone; so had the fine carving in bone and +antler. Smaller, speedier animals were moving into the new forests. New +ways of hunting them, or ways of getting other food, had to be found. +Hence, new tools and weapons were necessary. Some of the people who +moved into northern Germany were successful reindeer hunters. Then the +reindeer moved off to the north, and again new sources of food had to +be found. + + +THE READJUSTMENTS COMPLETED IN EUROPE + +After a few thousand years, things began to look better. Or at least +we can say this: By about 6000 B.C. we again get hotter archeological +materials. The best of these come from the north European area: +Britain, Belgium, Holland, Denmark, north Germany, southern Norway and +Sweden. Much of this north European material comes from bogs and swamps +where it had become water-logged and has kept very well. Thus we have +much more complete _assemblages_[4] than for any time earlier. + + [4] “Assemblage” is a useful word when there are different kinds of + archeological materials belonging together, from one area and of + one time. An assemblage is made up of a number of “industries” + (that is, all the tools in chipped stone, all the tools in + bone, all the tools in wood, the traces of houses, etc.) and + everything else that manages to survive, such as the art, the + burials, the bones of the animals used as food, and the traces + of plant foods; in fact, everything that has been left to us + and can be used to help reconstruct the lives of the people to + whom it once belonged. Our own present-day “assemblage” would be + the sum total of all the objects in our mail-order catalogues, + department stores and supply houses of every sort, our churches, + our art galleries and other buildings, together with our roads, + canals, dams, irrigation ditches, and any other traces we might + leave of ourselves, from graves to garbage dumps. Not everything + would last, so that an archeologist digging us up--say 2,000 + years from now--would find only the most durable items in our + assemblage. + +The best known of these assemblages is the _Maglemosian_, named after a +great Danish peat-swamp where much has been found. + +[Illustration: SKETCH OF MAGLEMOSIAN ASSEMBLAGE + + CHIPPED STONE + HEMP + GROUND STONE + BONE AND ANTLER + WOOD] + +In the Maglemosian assemblage the flint industry was still very +important. Blade tools, tanged arrow points, and burins were still +made, but there were also axes for cutting the trees in the new +forests. Moreover, the tiny microlithic blades, in a variety of +geometric forms, are also found. Thus, a specialized tradition that +possibly began east of the Mediterranean had reached northern Europe. +There was also a ground stone industry; some axes and club-heads were +made by grinding and polishing rather than by chipping. The industries +in bone and antler show a great variety of tools: axes, fish-hooks, +fish spears, handles and hafts for other tools, harpoons, and clubs. +A remarkable industry in wood has been preserved. Paddles, sled +runners, handles for tools, and bark floats for fish-nets have been +found. There are even fish-nets made of plant fibers. Canoes of some +kind were no doubt made. Bone and antler tools were decorated with +simple patterns, and amber was collected. Wooden bows and arrows are +found. + +It seems likely that the Maglemosian bog finds are remains of summer +camps, and that in winter the people moved to higher and drier regions. +Childe calls them the “Forest folk”; they probably lived much the +same sort of life as did our pre-agricultural Indians of the north +central states. They hunted small game or deer; they did a great deal +of fishing; they collected what plant food they could find. In fact, +their assemblage shows us again that remarkable ability of men to adapt +themselves to change. They had succeeded in domesticating the dog; he +was still a very wolf-like dog, but his long association with mankind +had now begun. Professor Coon believes that these people were direct +descendants of the men of the glacial age and that they had much the +same appearance. He believes that most of the Ice Age survivors still +extant are living today in the northwestern European area. + + +SOUTH AND CENTRAL EUROPE PERHAPS AS READJUSTED AS THE NORTH + +There is always one trouble with things that come from areas where +preservation is exceptionally good: The very quantity of materials in +such an assemblage tends to make things from other areas look poor +and simple, although they may not have been so originally at all. The +assemblages of the people who lived to the south of the Maglemosian +area may also have been quite large and varied; but, unfortunately, +relatively little of the southern assemblages has lasted. The +water-logged sites of the Maglemosian area preserved a great deal +more. Hence the Maglemosian itself _looks_ quite advanced to us, when +we compare it with the few things that have happened to last in other +areas. If we could go back and wander over the Europe of eight thousand +years ago, we would probably find that the peoples of France, central +Europe, and south central Russia were just as advanced as those of the +north European-Baltic belt. + +South of the north European belt the hunting-food-collecting peoples +were living on as best they could during this time. One interesting +group, which seems to have kept to the regions of sandy soil and scrub +forest, made great quantities of geometric microliths. These are the +materials called _Tardenoisian_. The materials of the “Forest folk” of +France and central Europe generally are called _Azilian_; Dr. Movius +believes the term might best be restricted to the area south of the +Loire River. + + +HOW MUCH REAL CHANGE WAS THERE? + +You can see that no really _basic_ change in the way of life has yet +been described. Childe sees the problem that faced the Europeans of +10,000 to 3000 B.C. as a problem in readaptation to the post-glacial +forest environment. By 6000 B.C. some quite successful solutions of +the problem--like the Maglemosian--had been made. The upsets that came +with the melting of the last ice gradually brought about all sorts of +changes in the tools and food-getting habits, but the people themselves +were still just as much simple hunters, fishers, and food-collectors as +they had been in 25,000 B.C. It could be said that they changed just +enough so that they would not have to change. But there is a bit more +to it than this. + +Professor Mathiassen of Copenhagen, who knows the archeological remains +of this time very well, poses a question. He speaks of the material +as being neither rich nor progressive, in fact “rather stagnant,” but +he goes on to add that the people had a certain “receptiveness” and +were able to adapt themselves quickly when the next change did come. +My own understanding of the situation is that the “Forest folk” made +nothing as spectacular as had the producers of the earlier Magdalenian +assemblage and the Franco-Cantabrian art. On the other hand, they +_seem_ to have been making many more different kinds of tools for many +more different kinds of tasks than had their Ice Age forerunners. I +emphasize “seem” because the preservation in the Maglemosian bogs +is very complete; certainly we cannot list anywhere near as many +different things for earlier times as we did for the Maglemosians +(p. 94). I believe this experimentation with all kinds of new tools +and gadgets, this intensification of adaptiveness (p. 91), this +“receptiveness,” even if it is still only pointed toward hunting, +fishing, and food-collecting, is an important thing. + +Remember that the only marker we have handy for the _beginning_ of +this tendency toward “receptiveness” and experimentation is the +little microlithic blade tools of various geometric forms. These, we +saw, began before the last ice had melted away, and they lasted on +in use for a very long time. I wish there were a better marker than +the microliths but I do not know of one. Remember, too, that as yet +we can only use the microliths as a marker in Europe and about the +Mediterranean. + + +CHANGES IN OTHER AREAS? + +All this last section was about Europe. How about the rest of the world +when the last glaciers were melting away? + +We simply don’t know much about this particular time in other parts +of the world except in Europe, the Mediterranean basin and the Middle +East. People were certainly continuing to move into the New World by +way of Siberia and the Bering Strait about this time. But for the +greater part of Africa and Asia, we do not know exactly what was +happening. Some day, we shall no doubt find out; today we are without +clear information. + + +REAL CHANGE AND PRELUDE IN THE NEAR EAST + +The appearance of the microliths and the developments made by the +“Forest folk” of northwestern Europe also mark an end. They show us +the terminal phase of the old food-collecting way of life. It grows +increasingly clear that at about the same time that the Maglemosian and +other “Forest folk” were adapting themselves to hunting, fishing, and +collecting in new ways to fit the post-glacial environment, something +completely new was being made ready in western Asia. + +Unfortunately, we do not have as much understanding of the climate and +environment of the late Ice Age in western Asia as we have for most +of Europe. Probably the weather was never so violent or life quite +so rugged as it was in northern Europe. We know that the microliths +made their appearance in western Asia at least by 10,000 B.C. and +possibly earlier, marking the beginning of the terminal phase of +food-collecting. Then, gradually, we begin to see the build-up towards +the first _basic change_ in human life. + +This change amounted to a revolution just as important as the +Industrial Revolution. In it, men first learned to domesticate +plants and animals. They began _producing_ their food instead of +simply gathering or collecting it. When their food-production +became reasonably effective, people could and did settle down in +village-farming communities. With the appearance of the little farming +villages, a new way of life was actually under way. Professor Childe +has good reason to speak of the “food-producing revolution,” for it was +indeed a revolution. + + +QUESTIONS ABOUT CAUSE + +We do not yet know _how_ and _why_ this great revolution took place. We +are only just beginning to put the questions properly. I suspect the +answers will concern some delicate and subtle interplay between man and +nature. Clearly, both the level of culture and the natural condition of +the environment must have been ready for the great change, before the +change itself could come about. + +It is going to take years of co-operative field work by both +archeologists and the natural scientists who are most helpful to them +before the _how_ and _why_ answers begin to appear. Anthropologically +trained archeologists are fascinated with the cultures of men in times +of great change. About ten or twelve thousand years ago, the general +level of culture in many parts of the world seems to have been ready +for change. In northwestern Europe, we saw that cultures “changed +just enough so that they would not have to change.” We linked this to +environmental changes with the coming of post-glacial times. + +In western Asia, we archeologists can prove that the food-producing +revolution actually took place. We can see _the_ important consequence +of effective domestication of plants and animals in the appearance of +the settled village-farming community. And within the village-farming +community was the seed of civilization. The way in which effective +domestication of plants and animals came about, however, must also be +linked closely with the natural environment. Thus the archeologists +will not solve the _how_ and _why_ questions alone--they will need the +help of interested natural scientists in the field itself. + + +PRECONDITIONS FOR THE REVOLUTION + +Especially at this point in our story, we must remember how culture and +environment go hand in hand. Neither plants nor animals domesticate +themselves; men domesticate them. Furthermore, men usually domesticate +only those plants and animals which are useful. There is a good +question here: What is cultural usefulness? But I shall side-step it to +save time. Men cannot domesticate plants and animals that do not exist +in the environment where the men live. Also, there are certainly some +animals and probably some plants that resist domestication, although +they might be useful. + +This brings me back again to the point that _both_ the level of culture +and the natural condition of the environment--with the proper plants +and animals in it--must have been ready before domestication could +have happened. But this is precondition, not cause. Why did effective +food-production happen first in the Near East? Why did it happen +independently in the New World slightly later? Why also in the Far +East? Why did it happen at all? Why are all human beings not still +living as the Maglemosians did? These are the questions we still have +to face. + + +CULTURAL “RECEPTIVENESS” AND PROMISING ENVIRONMENTS + +Until the archeologists and the natural scientists--botanists, +geologists, zoologists, and general ecologists--have spent many more +years on the problem, we shall not have full _how_ and _why_ answers. I +do think, however, that we are beginning to understand what to look for. + +We shall have to learn much more of what makes the cultures of men +“receptive” and experimental. Did change in the environment alone +force it? Was it simply a case of Professor Toynbee’s “challenge and +response?” I cannot believe the answer is quite that simple. Were it +so simple, we should want to know why the change hadn’t come earlier, +along with earlier environmental changes. We shall not know the answer, +however, until we have excavated the traces of many more cultures of +the time in question. We shall doubtless also have to learn more about, +and think imaginatively about, the simpler cultures still left today. +The “mechanics” of culture in general will be bound to interest us. + +It will also be necessary to learn much more of the environments of +10,000 to 12,000 years ago. In which regions of the world were the +natural conditions most promising? Did this promise include plants and +animals which could be domesticated, or did it only offer new ways of +food-collecting? There is much work to do on this problem, but we are +beginning to get some general hints. + +Before I begin to detail the hints we now have from western Asia, I +want to do two things. First, I shall tell you of an old theory as to +how food-production might have appeared. Second, I will bother you with +some definitions which should help us in our thinking as the story goes +on. + + +AN OLD THEORY AS TO THE CAUSE OF THE REVOLUTION + +The idea that change would result, if the balance between nature +and culture became upset, is of course not a new one. For at least +twenty-five years, there has been a general theory as to _how_ the +food-producing revolution happened. This theory depends directly on the +idea of natural change in the environment. + +The five thousand years following about 10,000 B.C. must have been +very difficult ones, the theory begins. These were the years when +the most marked melting of the last glaciers was going on. While the +glaciers were in place, the climate to the south of them must have been +different from the climate in those areas today. You have no doubt read +that people once lived in regions now covered by the Sahara Desert. +This is true; just when is not entirely clear. The theory is that +during the time of the glaciers, there was a broad belt of rain winds +south of the glaciers. These rain winds would have kept north Africa, +the Nile Valley, and the Middle East green and fertile. But when the +glaciers melted back to the north, the belt of rain winds is supposed +to have moved north too. Then the people living south and east of the +Mediterranean would have found that their water supply was drying up, +that the animals they hunted were dying or moving away, and that the +plant foods they collected were dried up and scarce. + +According to the theory, all this would have been true except in the +valleys of rivers and in oases in the growing deserts. Here, in the +only places where water was left, the men and animals and plants would +have clustered. They would have been forced to live close to one +another, in order to live at all. Presently the men would have seen +that some animals were more useful or made better food than others, +and so they would have begun to protect these animals from their +natural enemies. The men would also have been forced to try new plant +foods--foods which possibly had to be prepared before they could be +eaten. Thus, with trials and errors, but by being forced to live close +to plants and animals, men would have learned to domesticate them. + + +THE OLD THEORY TOO SIMPLE FOR THE FACTS + +This theory was set up before we really knew anything in detail about +the later prehistory of the Near and Middle East. We now know that +the facts which have been found don’t fit the old theory at all well. +Also, I have yet to find an American meteorologist who feels that we +know enough about the changes in the weather pattern to say that it can +have been so simple and direct. And, of course, the glacial ice which +began melting after 12,000 years ago was merely the last sub-phase of +the last great glaciation. There had also been three earlier periods +of great alpine glaciers, and long periods of warm weather in between. +If the rain belt moved north as the glaciers melted for the last time, +it must have moved in the same direction in earlier times. Thus, the +forced neighborliness of men, plants, and animals in river valleys and +oases must also have happened earlier. Why didn’t domestication happen +earlier, then? + +Furthermore, it does not seem to be in the oases and river valleys +that we have our first or only traces of either food-production +or the earliest farming villages. These traces are also in the +hill-flanks of the mountains of western Asia. Our earliest sites of the +village-farmers do not seem to indicate a greatly different climate +from that which the same region now shows. In fact, everything we now +know suggests that the old theory was just too simple an explanation to +have been the true one. The only reason I mention it--beyond correcting +the ideas you may get in the general texts--is that it illustrates the +kind of thinking we shall have to do, even if it is doubtless wrong in +detail. + +We archeologists shall have to depend much more than we ever have on +the natural scientists who can really help us. I can tell you this from +experience. I had the great good fortune to have on my expedition staff +in Iraq in 1954-55, a geologist, a botanist, and a zoologist. Their +studies added whole new bands of color to my spectrum of thinking about +_how_ and _why_ the revolution took place and how the village-farming +community began. But it was only a beginning; as I said earlier, we are +just now learning to ask the proper questions. + + +ABOUT STAGES AND ERAS + +Now come some definitions, so I may describe my material more easily. +Archeologists have always loved to make divisions and subdivisions +within the long range of materials which they have found. They often +disagree violently about which particular assemblage of material +goes into which subdivision, about what the subdivisions should be +named, about what the subdivisions really mean culturally. Some +archeologists, probably through habit, favor an old scheme of Grecized +names for the subdivisions: paleolithic, mesolithic, neolithic. I +refuse to use these words myself. They have meant too many different +things to too many different people and have tended to hide some pretty +fuzzy thinking. Probably you haven’t even noticed my own scheme of +subdivision up to now, but I’d better tell you in general what it is. + +I think of the earliest great group of archeological materials, from +which we can deduce only a food-gathering way of culture, as the +_food-gathering stage_. I say “stage” rather than “age,” because it +is not quite over yet; there are still a few primitive people in +out-of-the-way parts of the world who remain in the _food-gathering +stage_. In fact, Professor Julian Steward would probably prefer to call +it a food-gathering _level_ of existence, rather than a stage. This +would be perfectly acceptable to me. I also tend to find myself using +_collecting_, rather than _gathering_, for the more recent aspects or +era of the stage, as the word “collecting” appears to have more sense +of purposefulness and specialization than does “gathering” (see p. +91). + +Now, while I think we could make several possible subdivisions of the +food-gathering stage--I call my subdivisions of stages _eras_[5]--I +believe the only one which means much to us here is the last or +_terminal sub-era of food-collecting_ of the whole food-gathering +stage. The microliths seem to mark its approach in the northwestern +part of the Old World. It is really shown best in the Old World by +the materials of the “Forest folk,” the cultural adaptation to the +post-glacial environment in northwestern Europe. We talked about +the “Forest folk” at the beginning of this chapter, and I used the +Maglemosian assemblage of Denmark as an example. + + [5] It is difficult to find words which have a sequence or gradation + of meaning with respect to both development and a range of time + in the past, or with a range of time from somewhere in the past + which is perhaps not yet ended. One standard Webster definition + of _stage_ is: “One of the steps into which the material + development of man ... is divided.” I cannot find any dictionary + definition that suggests which of the words, _stage_ or _era_, + has the meaning of a longer span of time. Therefore, I have + chosen to let my eras be shorter, and to subdivide my stages + into eras. Webster gives _era_ as: “A signal stage of history, + an epoch.” When I want to subdivide my eras, I find myself using + _sub-eras_. Thus I speak of the _eras_ within a _stage_ and of + the _sub-eras_ within an _era_; that is, I do so when I feel + that I really have to, and when the evidence is clear enough to + allow it. + +The food-producing revolution ushers in the _food-producing stage_. +This stage began to be replaced by the _industrial stage_ only about +two hundred years ago. Now notice that my stage divisions are in terms +of technology and economics. We must think sharply to be sure that the +subdivisions of the stages, the eras, are in the same terms. This does +not mean that I think technology and economics are the only important +realms of culture. It is rather that for most of prehistoric time the +materials left to the archeologists tend to limit our deductions to +technology and economics. + +I’m so soon out of my competence, as conventional ancient history +begins, that I shall only suggest the earlier eras of the +food-producing stage to you. This book is about prehistory, and I’m not +a universal historian. + + +THE TWO EARLIEST ERAS OF THE FOOD-PRODUCING STAGE + +The food-producing stage seems to appear in western Asia with really +revolutionary suddenness. It is seen by the relative speed with which +the traces of new crafts appear in the earliest village-farming +community sites we’ve dug. It is seen by the spread and multiplication +of these sites themselves, and the remarkable growth in human +population we deduce from this increase in sites. We’ll look at some +of these sites and the archeological traces they yield in the next +chapter. When such village sites begin to appear, I believe we are in +the _era of the primary village-farming community_. I also believe this +is the second era of the food-producing stage. + +The first era of the food-producing stage, I believe, was an _era of +incipient cultivation and animal domestication_. I keep saying “I +believe” because the actual evidence for this earlier era is so slight +that one has to set it up mainly by playing a hunch for it. The reason +for playing the hunch goes about as follows. + +One thing we seem to be able to see, in the food-collecting era in +general, is a tendency for people to begin to settle down. This +settling down seemed to become further intensified in the terminal +era. How this is connected with Professor Mathiassen’s “receptiveness” +and the tendency to be experimental, we do not exactly know. The +evidence from the New World comes into play here as well as that from +the Old World. With this settling down in one place, the people of the +terminal era--especially the “Forest folk” whom we know best--began +making a great variety of new things. I remarked about this earlier in +the chapter. Dr. Robert M. Adams is of the opinion that this atmosphere +of experimentation with new tools--with new ways of collecting food--is +the kind of atmosphere in which one might expect trials at planting +and at animal domestication to have been made. We first begin to find +traces of more permanent life in outdoor camp sites, although caves +were still inhabited at the beginning of the terminal era. It is not +surprising at all that the “Forest folk” had already domesticated the +dog. In this sense, the whole era of food-collecting was becoming ready +and almost “incipient” for cultivation and animal domestication. + +Northwestern Europe was not the place for really effective beginnings +in agriculture and animal domestication. These would have had to take +place in one of those natural environments of promise, where a variety +of plants and animals, each possible of domestication, was available in +the wild state. Let me spell this out. Really effective food-production +must include a variety of items to make up a reasonably well-rounded +diet. The food-supply so produced must be trustworthy, even though +the food-producing peoples themselves might be happy to supplement +it with fish and wild strawberries, just as we do when such things +are available. So, as we said earlier, part of our problem is that +of finding a region with a natural environment which includes--and +did include, some ten thousand years ago--a variety of possibly +domesticable wild plants and animals. + + +NUCLEAR AREAS + +Now comes the last of my definitions. A region with a natural +environment which included a variety of wild plants and animals, +both possible and ready for domestication, would be a central +or core or _nuclear area_, that is, it would be when and _if_ +food-production took place within it. It is pretty hard for me to +imagine food-production having ever made an independent start outside +such a nuclear area, although there may be some possible nuclear areas +in which food-production never took place (possibly in parts of Africa, +for example). + +We know of several such nuclear areas. In the New World, Middle America +and the Andean highlands make up one or two; it is my understanding +that the evidence is not yet clear as to which. There seems to have +been a nuclear area somewhere in southeastern Asia, in the Malay +peninsula or Burma perhaps, connected with the early cultivation of +taro, breadfruit, the banana and the mango. Possibly the cultivation +of rice and the domestication of the chicken and of zebu cattle and +the water buffalo belong to this southeast Asiatic nuclear area. We +know relatively little about it archeologically, as yet. The nuclear +area which was the scene of the earliest experiment in effective +food-production was in western Asia. Since I know it best, I shall use +it as my example. + + +THE NUCLEAR NEAR EAST + +The nuclear area of western Asia is naturally the one of greatest +interest to people of the western cultural tradition. Our cultural +heritage began within it. The area itself is the region of the hilly +flanks of rain-watered grass-land which build up to the high mountain +ridges of Iran, Iraq, Turkey, Syria, and Palestine. The map on page +125 indicates the region. If you have a good atlas, try to locate the +zone which surrounds the drainage basin of the Tigris and Euphrates +Rivers at elevations of from approximately 2,000 to 5,000 feet. The +lower alluvial land of the Tigris-Euphrates basin itself has very +little rainfall. Some years ago Professor James Henry Breasted called +the alluvial lands of the Tigris-Euphrates a part of the “fertile +crescent.” These alluvial lands are very fertile if irrigated. Breasted +was most interested in the oriental civilizations of conventional +ancient history, and irrigation had been discovered before they +appeared. + +The country of hilly flanks above Breasted’s crescent receives from +10 to 20 or more inches of winter rainfall each year, which is about +what Kansas has. Above the hilly-flanks zone tower the peaks and ridges +of the Lebanon-Amanus chain bordering the coast-line from Palestine +to Turkey, the Taurus Mountains of southern Turkey, and the Zagros +range of the Iraq-Iran borderland. This rugged mountain frame for our +hilly-flanks zone rises to some magnificent alpine scenery, with peaks +of from ten to fifteen thousand feet in elevation. There are several +gaps in the Mediterranean coastal portion of the frame, through which +the winter’s rain-bearing winds from the sea may break so as to carry +rain to the foothills of the Taurus and the Zagros. + +The picture I hope you will have from this description is that of an +intermediate hilly-flanks zone lying between two regions of extremes. +The lower Tigris-Euphrates basin land is low and far too dry and hot +for agriculture based on rainfall alone; to the south and southwest, it +merges directly into the great desert of Arabia. The mountains which +lie above the hilly-flanks zone are much too high and rugged to have +encouraged farmers. + + +THE NATURAL ENVIRONMENT OF THE NUCLEAR NEAR EAST + +The more we learn of this hilly-flanks zone that I describe, the +more it seems surely to have been a nuclear area. This is where we +archeologists need, and are beginning to get, the help of natural +scientists. They are coming to the conclusion that the natural +environment of the hilly-flanks zone today is much as it was some eight +to ten thousand years ago. There are still two kinds of wild wheat and +a wild barley, and the wild sheep, goat, and pig. We have discovered +traces of each of these at about nine thousand years ago, also traces +of wild ox, horse, and dog, each of which appears to be the probable +ancestor of the domesticated form. In fact, at about nine thousand +years ago, the two wheats, the barley, and at least the goat, were +already well on the road to domestication. + +The wild wheats give us an interesting clue. They are only available +together with the wild barley within the hilly-flanks zone. While the +wild barley grows in a variety of elevations and beyond the zone, +at least one of the wild wheats does not seem to grow below the hill +country. As things look at the moment, the domestication of both the +wheats together could _only_ have taken place within the hilly-flanks +zone. Barley seems to have first come into cultivation due to its +presence as a weed in already cultivated wheat fields. There is also +a suggestion--there is still much more to learn in the matter--that +the animals which were first domesticated were most at home up in the +hilly-flanks zone in their wild state. + +With a single exception--that of the dog--the earliest positive +evidence of domestication includes the two forms of wheat, the barley, +and the goat. The evidence comes from within the hilly-flanks zone. +However, it comes from a settled village proper, Jarmo (which I’ll +describe in the next chapter), and is thus from the era of the primary +village-farming community. We are still without positive evidence of +domesticated grain and animals in the first era of the food-producing +stage, that of incipient cultivation and animal domestication. + + +THE ERA OF INCIPIENT CULTIVATION AND ANIMAL DOMESTICATION + +I said above (p. 105) that my era of incipient cultivation and animal +domestication is mainly set up by playing a hunch. Although we cannot +really demonstrate it--and certainly not in the Near East--it would +be very strange for food-collectors not to have known a great deal +about the plants and animals most useful to them. They do seem to have +domesticated the dog. We can easily imagine them remembering to go +back, season after season, to a particular patch of ground where seeds +or acorns or berries grew particularly well. Most human beings, unless +they are extremely hungry, are attracted to baby animals, and many wild +pups or fawns or piglets must have been brought back alive by hunting +parties. + +In this last sense, man has probably always been an incipient +cultivator and domesticator. But I believe that Adams is right in +suggesting that this would be doubly true with the experimenters of +the terminal era of food-collecting. We noticed that they also seem +to have had a tendency to settle down. Now my hunch goes that _when_ +this experimentation and settling down took place within a potential +nuclear area--where a whole constellation of plants and animals +possible of domestication was available--the change was easily made. +Professor Charles A. Reed, our field colleague in zoology, agrees that +year-round settlement with plant domestication probably came before +there were important animal domestications. + + +INCIPIENT ERAS AND NUCLEAR AREAS + +I have put this scheme into a simple chart (p. 111) with the names +of a few of the sites we are going to talk about. You will see that my +hunch means that there are eras of incipient cultivation _only_ within +nuclear areas. In a nuclear area, the terminal era of food-collecting +would probably have been quite short. I do not know for how long a time +the era of incipient cultivation and domestication would have lasted, +but perhaps for several thousand years. Then it passed on into the era +of the primary village-farming community. + +Outside a nuclear area, the terminal era of food-collecting would last +for a long time; in a few out-of-the-way parts of the world, it still +hangs on. It would end in any particular place through contact with +and the spread of ideas of people who had passed on into one of the +more developed eras. In many cases, the terminal era of food-collecting +was ended by the incoming of the food-producing peoples themselves. +For example, the practices of food-production were carried into Europe +by the actual movement of some numbers of peoples (we don’t know how +many) who had reached at least the level of the primary village-farming +community. The “Forest folk” learned food-production from them. There +was never an era of incipient cultivation and domestication proper in +Europe, if my hunch is right. + + +ARCHEOLOGICAL DIFFICULTIES IN SEEING THE INCIPIENT ERA + +The way I see it, two things were required in order that an era of +incipient cultivation and domestication could begin. First, there had +to be the natural environment of a nuclear area, with its whole group +of plants and animals capable of domestication. This is the aspect of +the matter which we’ve said is directly given by nature. But it is +quite possible that such an environment with such a group of plants +and animals in it may have existed well before ten thousand years ago +in the Near East. It is also quite possible that the same promising +condition may have existed in regions which never developed into +nuclear areas proper. Here, again, we come back to the cultural factor. +I think it was that “atmosphere of experimentation” we’ve talked about +once or twice before. I can’t define it for you, other than to say that +by the end of the Ice Age, the general level of many cultures was ready +for change. Ask me how and why this was so, and I’ll tell you we don’t +know yet, and that if we did understand this kind of question, there +would be no need for me to go on being a prehistorian! + +[Illustration: POSSIBLE RELATIONSHIPS OF STAGES AND ERAS IN WESTERN +ASIA AND NORTHEASTERN AFRICA] + +Now since this was an era of incipience, of the birth of new ideas, +and of experimentation, it is very difficult to see its traces +archeologically. New tools having to do with the new ways of getting +and, in fact, producing food would have taken some time to develop. +It need not surprise us too much if we cannot find hoes for planting +and sickles for reaping grain at the very beginning. We might expect +a time of making-do with some of the older tools, or with make-shift +tools, for some of the new jobs. The present-day wild cousin of the +domesticated sheep still lives in the mountains of western Asia. It has +no wool, only a fine down under hair like that of a deer, so it need +not surprise us to find neither the whorls used for spinning nor traces +of woolen cloth. It must have taken some time for a wool-bearing sheep +to develop and also time for the invention of the new tools which go +with weaving. It would have been the same with other kinds of tools for +the new way of life. + +It is difficult even for an experienced comparative zoologist to tell +which are the bones of domesticated animals and which are those of +their wild cousins. This is especially so because the animal bones the +archeologists find are usually fragmentary. Furthermore, we do not have +a sort of library collection of the skeletons of the animals or an +herbarium of the plants of those times, against which the traces which +the archeologists find may be checked. We are only beginning to get +such collections for the modern wild forms of animals and plants from +some of our nuclear areas. In the nuclear area in the Near East, some +of the wild animals, at least, have already become extinct. There are +no longer wild cattle or wild horses in western Asia. We know they were +there from the finds we’ve made in caves of late Ice Age times, and +from some slightly later sites. + + +SITES WITH ANTIQUITIES OF THE INCIPIENT ERA + +So far, we know only a very few sites which would suit my notion of the +incipient era of cultivation and animal domestication. I am closing +this chapter with descriptions of two of the best Near Eastern examples +I know of. You may not be satisfied that what I am able to describe +makes a full-bodied era of development at all. Remember, however, that +I’ve told you I’m largely playing a kind of a hunch, and also that the +archeological materials of this era will always be extremely difficult +to interpret. At the beginning of any new way of life, there will be a +great tendency for people to make-do, at first, with tools and habits +they are already used to. I would suspect that a great deal of this +making-do went on almost to the end of this era. + + +THE NATUFIAN, AN ASSEMBLAGE OF THE INCIPIENT ERA + +The assemblage called the Natufian comes from the upper layers of a +number of caves in Palestine. Traces of its flint industry have also +turned up in Syria and Lebanon. We don’t know just how old it is. I +guess that it probably falls within five hundred years either way of +about 5000 B.C. + +Until recently, the people who produced the Natufian assemblage were +thought to have been only cave dwellers, but now at least three open +air Natufian sites have been briefly described. In their best-known +dwelling place, on Mount Carmel, the Natufian folk lived in the open +mouth of a large rock-shelter and on the terrace in front of it. On the +terrace, they had set at least two short curving lines of stones; but +these were hardly architecture; they seem more like benches or perhaps +the low walls of open pens. There were also one or two small clusters +of stones laid like paving, and a ring of stones around a hearth or +fireplace. One very round and regular basin-shaped depression had been +cut into the rocky floor of the terrace, and there were other less +regular basin-like depressions. In the newly reported open air sites, +there seem to have been huts with rounded corners. + +Most of the finds in the Natufian layer of the Mount Carmel cave were +flints. About 80 per cent of these flint tools were microliths made +by the regular working of tiny blades into various tools, some having +geometric forms. The larger flint tools included backed blades, burins, +scrapers, a few arrow points, some larger hacking or picking tools, and +one special type. This last was the sickle blade. + +We know a sickle blade of flint when we see one, because of a strange +polish or sheen which seems to develop on the cutting edge when the +blade has been used to cut grasses or grain, or--perhaps--reeds. In +the Natufian, we have even found the straight bone handles in which a +number of flint sickle blades were set in a line. + +There was a small industry in ground or pecked stone (that is, abraded +not chipped) in the Natufian. This included some pestle and mortar +fragments. The mortars are said to have a deep and narrow hole, +and some of the pestles show traces of red ochre. We are not sure +that these mortars and pestles were also used for grinding food. In +addition, there were one or two bits of carving in stone. + + +NATUFIAN ANTIQUITIES IN OTHER MATERIALS; BURIALS AND PEOPLE + +The Natufian industry in bone was quite rich. It included, beside the +sickle hafts mentioned above, points and harpoons, straight and curved +types of fish-hooks, awls, pins and needles, and a variety of beads and +pendants. There were also beads and pendants of pierced teeth and shell. + +A number of Natufian burials have been found in the caves; some burials +were grouped together in one grave. The people who were buried within +the Mount Carmel cave were laid on their backs in an extended position, +while those on the terrace seem to have been “flexed” (placed in their +graves in a curled-up position). This may mean no more than that it was +easier to dig a long hole in cave dirt than in the hard-packed dirt of +the terrace. The people often had some kind of object buried with them, +and several of the best collections of beads come from the burials. On +two of the skulls there were traces of elaborate head-dresses of shell +beads. + +[Illustration: SKETCH OF NATUFIAN ASSEMBLAGE + + MICROLITHS + ARCHITECTURE? + BURIAL + CHIPPED STONE + GROUND STONE + BONE] + +The animal bones of the Natufian layers show beasts of a “modern” type, +but with some differences from those of present-day Palestine. The +bones of the gazelle far outnumber those of the deer; since gazelles +like a much drier climate than deer, Palestine must then have had much +the same climate that it has today. Some of the animal bones were those +of large or dangerous beasts: the hyena, the bear, the wild boar, +and the leopard. But the Natufian people may have had the help of a +large domesticated dog. If our guess at a date for the Natufian is +right (about 7750 B.C.), this is an earlier dog than was that in the +Maglemosian of northern Europe. More recently, it has been reported +that a domesticated goat is also part of the Natufian finds. + +The study of the human bones from the Natufian burials is not yet +complete. Until Professor McCown’s study becomes available, we may note +Professor Coon’s assessment that these people were of a “basically +Mediterranean type.” + + +THE KARIM SHAHIR ASSEMBLAGE + +Karim Shahir differs from the Natufian sites in that it shows traces +of a temporary open site or encampment. It lies on the top of a bluff +in the Kurdish hill-country of northeastern Iraq. It was dug by Dr. +Bruce Howe of the expedition I directed in 1950-51 for the Oriental +Institute and the American Schools of Oriental Research. In 1954-55, +our expedition located another site, M’lefaat, with general resemblance +to Karim Shahir, but about a hundred miles north of it. In 1956, Dr. +Ralph Solecki located still another Karim Shahir type of site called +Zawi Chemi Shanidar. The Zawi Chemi site has a radiocarbon date of 8900 +± 300 B.C. + +Karim Shahir has evidence of only one very shallow level of occupation. +It was probably not lived on very long, although the people who lived +on it spread out over about three acres of area. In spots, the single +layer yielded great numbers of fist-sized cracked pieces of limestone, +which had been carried up from the bed of a stream at the bottom of the +bluff. We think these cracked stones had something to do with a kind of +architecture, but we were unable to find positive traces of hut plans. +At M’lefaat and Zawi Chemi, there were traces of rounded hut plans. + +As in the Natufian, the great bulk of small objects of the Karim Shahir +assemblage was in chipped flint. A large proportion of the flint tools +were microlithic bladelets and geometric forms. The flint sickle blade +was almost non-existent, being far scarcer than in the Natufian. The +people of Karim Shahir did a modest amount of work in the grinding of +stone; there were milling stone fragments of both the mortar and the +quern type, and stone hoes or axes with polished bits. Beads, pendants, +rings, and bracelets were made of finer quality stone. We found a few +simple points and needles of bone, and even two rather formless unbaked +clay figurines which seemed to be of animal form. + +[Illustration: SKETCH OF KARIM SHAHIR ASSEMBLAGE + + CHIPPED STONE + GROUND STONE + UNBAKED CLAY + SHELL + BONE + “ARCHITECTURE”] + +Karim Shahir did not yield direct evidence of the kind of vegetable +food its people ate. The animal bones showed a considerable +increase in the proportion of the bones of the species capable of +domestication--sheep, goat, cattle, horse, dog--as compared with animal +bones from the earlier cave sites of the area, which have a high +proportion of bones of wild forms like deer and gazelle. But we do not +know that any of the Karim Shahir animals were actually domesticated. +Some of them may have been, in an “incipient” way, but we have no means +at the moment that will tell us from the bones alone. + + +WERE THE NATUFIAN AND KARIM SHAHIR PEOPLES FOOD-PRODUCERS? + +It is clear that a great part of the food of the Natufian people +must have been hunted or collected. Shells of land, fresh-water, and +sea animals occur in their cave layers. The same is true as regards +Karim Shahir, save for sea shells. But on the other hand, we have +the sickles, the milling stones, the possible Natufian dog, and the +goat, and the general animal situation at Karim Shahir to hint at an +incipient approach to food-production. At Karim Shahir, there was the +tendency to settle down out in the open; this is echoed by the new +reports of open air Natufian sites. The large number of cracked stones +certainly indicates that it was worth the peoples’ while to have some +kind of structure, even if the site as a whole was short-lived. + +It is a part of my hunch that these things all point toward +food-production--that the hints we seek are there. But in the sense +that the peoples of the era of the primary village-farming community, +which we shall look at next, are fully food-producing, the Natufian +and Karim Shahir folk had not yet arrived. I think they were part of +a general build-up to full scale food-production. They were possibly +controlling a few animals of several kinds and perhaps one or two +plants, without realizing the full possibilities of this “control” as a +new way of life. + +This is why I think of the Karim Shahir and Natufian folk as being at +a level, or in an era, of incipient cultivation and domestication. But +we shall have to do a great deal more excavation in this range of time +before we’ll get the kind of positive information we need. + + +SUMMARY + +I am sorry that this chapter has had to be so much more about ideas +than about the archeological traces of prehistoric men themselves. +But the antiquities of the incipient era of cultivation and animal +domestication will not be spectacular, even when we do have them +excavated in quantity. Few museums will be interested in these +antiquities for exhibition purposes. The charred bits or impressions +of plants, the fragments of animal bone and shell, and the varied +clues to climate and environment will be as important as the artifacts +themselves. It will be the ideas to which these traces lead us that +will be important. I am sure that this unspectacular material--when we +have much more of it, and learn how to understand what it says--will +lead us to how and why answers about the first great change in human +history. + +We know the earliest village-farming communities appeared in western +Asia, in a nuclear area. We do not yet know why the Near Eastern +experiment came first, or why it didn’t happen earlier in some other +nuclear area. Apparently, the level of culture and the promise of the +natural environment were ready first in western Asia. The next sites +we look at will show a simple but effective food-production already +in existence. Without effective food-production and the settled +village-farming communities, civilization never could have followed. +How effective food-production came into being by the end of the +incipient era, is, I believe, one of the most fascinating questions any +archeologist could face. + +It now seems probable--from possibly two of the Palestinian sites with +varieties of the Natufian (Jericho and Nahal Oren)--that there were +one or more local Palestinian developments out of the Natufian into +later times. In the same way, what followed after the Karim Shahir type +of assemblage in northeastern Iraq was in some ways a reflection of +beginnings made at Karim Shahir and Zawi Chemi. + + + + +THE First Revolution + +[Illustration] + + +As the incipient era of cultivation and animal domestication passed +onward into the era of the primary village-farming community, the first +basic change in human economy was fully achieved. In southwestern Asia, +this seems to have taken place about nine thousand years ago. I am +going to restrict my description to this earliest Near Eastern case--I +do not know enough about the later comparable experiments in the Far +East and in the New World. Let us first, once again, think of the +contrast between food-collecting and food-producing as ways of life. + + +THE DIFFERENCE BETWEEN FOOD-COLLECTORS AND FOOD-PRODUCERS + +Childe used the word “revolution” because of the radical change that +took place in the habits and customs of man. Food-collectors--that is, +hunters, fishers, berry- and nut-gatherers--had to live in small groups +or bands, for they had to be ready to move wherever their food supply +moved. Not many people can be fed in this way in one area, and small +children and old folks are a burden. There is not enough food to store, +and it is not the kind that can be stored for long. + +Do you see how this all fits into a picture? Small groups of people +living now in this cave, now in that--or out in the open--as they moved +after the animals they hunted; no permanent villages, a few half-buried +huts at best; no breakable utensils; no pottery; no signs of anything +for clothing beyond the tools that were probably used to dress the +skins of animals; no time to think of much of anything but food and +protection and disposal of the dead when death did come: an existence +which takes nature as it finds it, which does little or nothing to +modify nature--all in all, a savage’s existence, and a very tough one. +A man who spends his whole life following animals just to kill them to +eat, or moving from one berry patch to another, is really living just +like an animal himself. + + +THE FOOD-PRODUCING ECONOMY + +Against this picture let me try to draw another--that of man’s life +after food-production had begun. His meat was stored “on the hoof,” +his grain in silos or great pottery jars. He lived in a house: it was +worth his while to build one, because he couldn’t move far from his +fields and flocks. In his neighborhood enough food could be grown +and enough animals bred so that many people were kept busy. They all +lived close to their flocks and fields, in a village. The village was +already of a fair size, and it was growing, too. Everybody had more to +eat; they were presumably all stronger, and there were more children. +Children and old men could shepherd the animals by day or help with +the lighter work in the fields. After the crops had been harvested the +younger men might go hunting and some of them would fish, but the food +they brought in was only an addition to the food in the village; the +villagers wouldn’t starve, even if the hunters and fishermen came home +empty-handed. + +There was more time to do different things, too. They began to modify +nature. They made pottery out of raw clay, and textiles out of hair +or fiber. People who became good at pottery-making traded their pots +for food and spent all of their time on pottery alone. Other people +were learning to weave cloth or to make new tools. There were already +people in the village who were becoming full-time craftsmen. + +Other things were changing, too. The villagers must have had +to agree on new rules for living together. The head man of the +village had problems different from those of the chief of the small +food-collectors’ band. If somebody’s flock of sheep spoiled a wheat +field, the owner wanted payment for the grain he lost. The chief of +the hunters was never bothered with such questions. Even the gods +had changed. The spirits and the magic that had been used by hunters +weren’t of any use to the villagers. They needed gods who would watch +over the fields and the flocks, and they eventually began to erect +buildings where their gods might dwell, and where the men who knew most +about the gods might live. + + +WAS FOOD-PRODUCTION A “REVOLUTION”? + +If you can see the difference between these two pictures--between +life in the food-collecting stage and life after food-production +had begun--you’ll see why Professor Childe speaks of a revolution. +By revolution, he doesn’t mean that it happened over night or that +it happened only once. We don’t know exactly how long it took. Some +people think that all these changes may have occurred in less than +500 years, but I doubt that. The incipient era was probably an affair +of some duration. Once the level of the village-farming community had +been established, however, things did begin to move very fast. By +six thousand years ago, the descendants of the first villagers had +developed irrigation and plow agriculture in the relatively rainless +Mesopotamian alluvium and were living in towns with temples. Relative +to the half million years of food-gathering which lay behind, this had +been achieved with truly revolutionary suddenness. + + +GAPS IN OUR KNOWLEDGE OF THE NEAR EAST + +If you’ll look again at the chart (p. 111) you’ll see that I have +very few sites and assemblages to name in the incipient era of +cultivation and domestication, and not many in the earlier part of +the primary village-farming level either. Thanks in no small part +to the intelligent co-operation given foreign excavators by the +Iraq Directorate General of Antiquities, our understanding of the +sequence in Iraq is growing more complete. I shall use Iraq as my main +yard-stick here. But I am far from being able to show you a series of +Sears Roebuck catalogues, even century by century, for any part of +the nuclear area. There is still a great deal of earth to move, and a +great mass of material to recover and interpret before we even begin to +understand “how” and “why.” + +Perhaps here, because this kind of archeology is really my specialty, +you’ll excuse it if I become personal for a moment. I very much look +forward to having further part in closing some of the gaps in knowledge +of the Near East. This is not, as I’ve told you, the spectacular +range of Near Eastern archeology. There are no royal tombs, no gold, +no great buildings or sculpture, no writing, in fact nothing to +excite the normal museum at all. Nevertheless it is a range which, +idea-wise, gives the archeologist tremendous satisfaction. The country +of the hilly flanks is an exciting combination of green grasslands +and mountainous ridges. The Kurds, who inhabit the part of the area +in which I’ve worked most recently, are an extremely interesting and +hospitable people. Archeologists don’t become rich, but I’ll forego +the Cadillac for any bright spring morning in the Kurdish hills, on a +good site with a happy crew of workmen and an interested and efficient +staff. It is probably impossible to convey the full feeling which life +on such a dig holds--halcyon days for the body and acute pleasurable +stimulation for the mind. Old things coming newly out of the good dirt, +and the pieces of the human puzzle fitting into place! I think I am +an honest man; I cannot tell you that I am sorry the job is not yet +finished and that there are still gaps in this part of the Near Eastern +archeological sequence. + + +EARLIEST SITES OF THE VILLAGE FARMERS + +So far, the Karim Shahir type of assemblage, which we looked at in the +last chapter, is the earliest material available in what I take to +be the nuclear area. We do not believe that Karim Shahir was a village +site proper: it looks more like the traces of a temporary encampment. +Two caves, called Belt and Hotu, which are outside the nuclear area +and down on the foreshore of the Caspian Sea, have been excavated +by Professor Coon. These probably belong in the later extension of +the terminal era of food-gathering; in their upper layers are traits +like the use of pottery borrowed from the more developed era of the +same time in the nuclear area. The same general explanation doubtless +holds true for certain materials in Egypt, along the upper Nile and in +the Kharga oasis: these materials, called Sebilian III, the Khartoum +“neolithic,” and the Khargan microlithic, are from surface sites, +not from caves. The chart (p. 111) shows where I would place these +materials in era and time. + +[Illustration: THE HILLY FLANKS OF THE CRESCENT AND EARLY SITES OF THE +NEAR EAST] + +Both M’lefaat and Dr. Solecki’s Zawi Chemi Shanidar site appear to have +been slightly more “settled in” than was Karim Shahir itself. But I do +not think they belong to the era of farming-villages proper. The first +site of this era, in the hills of Iraqi Kurdistan, is Jarmo, on which +we have spent three seasons of work. Following Jarmo comes a variety of +sites and assemblages which lie along the hilly flanks of the crescent +and just below it. I am going to describe and illustrate some of these +for you. + +Since not very much archeological excavation has yet been done on sites +of this range of time, I shall have to mention the names of certain +single sites which now alone stand for an assemblage. This does not +mean that I think the individual sites I mention were unique. In the +times when their various cultures flourished, there must have been +many little villages which shared the same general assemblage. We are +only now beginning to locate them again. Thus, if I speak of Jarmo, +or Jericho, or Sialk as single examples of their particular kinds of +assemblages, I don’t mean that they were unique at all. I think I could +take you to the sites of at least three more Jarmos, within twenty +miles of the original one. They are there, but they simply haven’t yet +been excavated. In 1956, a Danish expedition discovered material of +Jarmo type at Shimshara, only two dozen miles northeast of Jarmo, and +below an assemblage of Hassunan type (which I shall describe presently). + + +THE GAP BETWEEN KARIM SHAHIR AND JARMO + +As we see the matter now, there is probably still a gap in the +available archeological record between the Karim Shahir-M’lefaat-Zawi +Chemi group (of the incipient era) and that of Jarmo (of the +village-farming era). Although some items of the Jarmo type materials +do reflect the beginnings of traditions set in the Karim Shahir group +(see p. 120), there is not a clear continuity. Moreover--to the +degree that we may trust a few radiocarbon dates--there would appear +to be around two thousand years of difference in time. The single +available Zawi Chemi “date” is 8900 ± 300 B.C.; the most reasonable +group of “dates” from Jarmo average to about 6750 ± 200 B.C. I am +uncertain about this two thousand years--I do not think it can have +been so long. + +This suggests that we still have much work to do in Iraq. You can +imagine how earnestly we await the return of political stability in the +Republic of Iraq. + + +JARMO, IN THE KURDISH HILLS, IRAQ + +The site of Jarmo has a depth of deposit of about twenty-seven feet, +and approximately a dozen layers of architectural renovation and +change. Nevertheless it is a “one period” site: its assemblage remains +essentially the same throughout, although one or two new items are +added in later levels. It covers about four acres of the top of a +bluff, below which runs a small stream. Jarmo lies in the hill country +east of the modern oil town of Kirkuk. The Iraq Directorate General of +Antiquities suggested that we look at it in 1948, and we have had three +seasons of digging on it since. + +The people of Jarmo grew the barley plant and two different kinds of +wheat. They made flint sickles with which to reap their grain, mortars +or querns on which to crack it, ovens in which it might be parched, and +stone bowls out of which they might eat their porridge. We are sure +that they had the domesticated goat, but Professor Reed (the staff +zoologist) is not convinced that the bones of the other potentially +domesticable animals of Jarmo--sheep, cattle, pig, horse, dog--show +sure signs of domestication. We had first thought that all of these +animals were domesticated ones, but Reed feels he must find out much +more before he can be sure. As well as their grain and the meat from +their animals, the people of Jarmo consumed great quantities of land +snails. Botanically, the Jarmo wheat stands about half way between +fully bred wheat and the wild forms. + + +ARCHITECTURE: HALL-MARK OF THE VILLAGE + +The sure sign of the village proper is in its traces of architectural +permanence. The houses of Jarmo were only the size of a small cottage +by our standards, but each was provided with several rectangular rooms. +The walls of the houses were made of puddled mud, often set on crude +foundations of stone. (The puddled mud wall, which the Arabs call +_touf_, is built by laying a three to six inch course of soft mud, +letting this sun-dry for a day or two, then adding the next course, +etc.) The village probably looked much like the simple Kurdish farming +village of today, with its mud-walled houses and low mud-on-brush +roofs. I doubt that the Jarmo village had more than twenty houses at +any one moment of its existence. Today, an average of about seven +people live in a comparable Kurdish house; probably the population of +Jarmo was about 150 people. + +[Illustration: SKETCH OF JARMO ASSEMBLAGE + + CHIPPED STONE + UNBAKED CLAY + GROUND STONE + POTTERY _UPPER THIRD OF SITE ONLY._ + REED MATTING + BONE + ARCHITECTURE] + +It is interesting that portable pottery does not appear until the +last third of the life of the Jarmo village. Throughout the duration +of the village, however, its people had experimented with the plastic +qualities of clay. They modeled little figurines of animals and of +human beings in clay; one type of human figurine they favored was that +of a markedly pregnant woman, probably the expression of some sort of +fertility spirit. They provided their house floors with baked-in-place +depressions, either as basins or hearths, and later with domed ovens of +clay. As we’ve noted, the houses themselves were of clay or mud; one +could almost say they were built up like a house-sized pot. Then, +finally, the idea of making portable pottery itself appeared, although +I very much doubt that the people of the Jarmo village discovered the +art. + +On the other hand, the old tradition of making flint blades and +microlithic tools was still very strong at Jarmo. The sickle-blade was +made in quantities, but so also were many of the much older tool types. +Strangely enough, it is within this age-old category of chipped stone +tools that we see one of the clearest pointers to a newer age. Many of +the Jarmo chipped stone tools--microliths--were made of obsidian, a +black volcanic natural glass. The obsidian beds nearest to Jarmo are +over three hundred miles to the north. Already a bulk carrying trade +had been established--the forerunner of commerce--and the routes were +set by which, in later times, the metal trade was to move. + +There are now twelve radioactive carbon “dates” from Jarmo. The most +reasonable cluster of determinations averages to about 6750 ± 200 +B.C., although there is a completely unreasonable range of “dates” +running from 3250 to 9250 B.C.! _If_ I am right in what I take to be +“reasonable,” the first flush of the food-producing revolution had been +achieved almost nine thousand years ago. + + +HASSUNA, IN UPPER MESOPOTAMIAN IRAQ + +We are not sure just how soon after Jarmo the next assemblage of Iraqi +material is to be placed. I do not think the time was long, and there +are a few hints that detailed habits in the making of pottery and +ground stone tools were actually continued from Jarmo times into the +time of the next full assemblage. This is called after a site named +Hassuna, a few miles to the south and west of modern Mosul. We also +have Hassunan type materials from several other sites in the same +general region. It is probably too soon to make generalizations about +it, but the Hassunan sites seem to cluster at slightly lower elevations +than those we have been talking about so far. + +The catalogue of the Hassuna assemblage is of course more full and +elaborate than that of Jarmo. The Iraqi government’s archeologists +who dug Hassuna itself, exposed evidence of increasing architectural +know-how. The walls of houses were still formed of puddled mud; +sun-dried bricks appear only in later periods. There were now several +different ways of making and decorating pottery vessels. One style of +pottery painting, called the Samarran style, is an extremely handsome +one and must have required a great deal of concentration and excellence +of draftsmanship. On the other hand, the old habits for the preparation +of good chipped stone tools--still apparent at Jarmo--seem to have +largely disappeared by Hassunan times. The flint work of the Hassunan +catalogue is, by and large, a wretched affair. We might guess that the +kinaesthetic concentration of the Hassuna craftsmen now went into other +categories; that is, they suddenly discovered they might have more fun +working with the newer materials. It’s a shame, for example, that none +of their weaving is preserved for us. + +The two available radiocarbon determinations from Hassunan contexts +stand at about 5100 and 5600 B.C. ± 250 years. + + +OTHER EARLY VILLAGE SITES IN THE NUCLEAR AREA + +I’ll now name and very briefly describe a few of the other early +village assemblages either in or adjacent to the hilly flanks of the +crescent. Unfortunately, we do not have radioactive carbon dates for +many of these materials. We may guess that some particular assemblage, +roughly comparable to that of Hassuna, for example, must reflect a +culture which lived at just about the same time as that of Hassuna. We +do this guessing on the basis of the general similarity and degree of +complexity of the Sears Roebuck catalogues of the particular assemblage +and that of Hassuna. We suppose that for sites near at hand and of a +comparable cultural level, as indicated by their generally similar +assemblages, the dating must be about the same. We may also know that +in a general stratigraphic sense, the sites in question may both appear +at the bottom of the ascending village sequence in their respective +areas. Without a number of consistent radioactive carbon dates, we +cannot be precise about priorities. + +[Illustration: SKETCH OF HASSUNA ASSEMBLAGE + + POTTERY + POTTERY OBJECTS + CHIPPED STONE + BONE + GROUND STONE + ARCHITECTURE + REED MATTING + BURIAL] + +The ancient mound at Jericho, in the Dead Sea valley in Palestine, +yields some very interesting material. Its catalogue somewhat resembles +that of Jarmo, especially in the sense that there is a fair depth +of deposit without portable pottery vessels. On the other hand, the +architecture of Jericho is surprisingly complex, with traces of massive +stone fortification walls and the general use of formed sun-dried +mud brick. Jericho lies in a somewhat strange and tropically lush +ecological niche, some seven hundred feet below sea level; it is +geographically within the hilly-flanks zone but environmentally not +part of it. + +Several radiocarbon “dates” for Jericho fall within the range of those +I find reasonable for Jarmo, and their internal statistical consistency +is far better than that for the Jarmo determinations. It is not yet +clear exactly what this means. + +The mound at Jericho (Tell es-Sultan) contains a remarkably +fine sequence, which perhaps does not have the gap we noted in +Iraqi-Kurdistan between the Karim Shahir group and Jarmo. While I am +not sure that the Jericho sequence will prove valid for those parts +of Palestine outside the special Dead Sea environmental niche, the +sequence does appear to proceed from the local variety of Natufian into +that of a very well settled community. So far, we have little direct +evidence for the food-production basis upon which the Jericho people +subsisted. + +There is an early village assemblage with strong characteristics of its +own in the land bordering the northeast corner of the Mediterranean +Sea, where Syria and the Cilician province of Turkey join. This early +Syro-Cilician assemblage must represent a general cultural pattern +which was at least in part contemporary with that of the Hassuna +assemblage. These materials from the bases of the mounds at Mersin, and +from Judaidah in the Amouq plain, as well as from a few other sites, +represent the remains of true villages. The walls of their houses were +built of puddled mud, but some of the house foundations were of stone. +Several different kinds of pottery were made by the people of these +villages. None of it resembles the pottery from Hassuna or from the +upper levels of Jarmo or Jericho. The Syro-Cilician people had not +lost their touch at working flint. An important southern variation of +the Syro-Cilician assemblage has been cleared recently at Byblos, a +port town famous in later Phoenician times. There are three radiocarbon +determinations which suggest that the time range for these developments +was in the sixth or early fifth millennium B.C. + +It would be fascinating to search for traces of even earlier +village-farming communities and for the remains of the incipient +cultivation era, in the Syro-Cilician region. + + +THE IRANIAN PLATEAU AND THE NILE VALLEY + +The map on page 125 shows some sites which lie either outside or in +an extension of the hilly-flanks zone proper. From the base of the +great mound at Sialk on the Iranian plateau came an assemblage of +early village material, generally similar, in the kinds of things it +contained, to the catalogues of Hassuna and Judaidah. The details of +how things were made are different; the Sialk assemblage represents +still another cultural pattern. I suspect it appeared a bit later +in time than did that of Hassuna. There is an important new item in +the Sialk catalogue. The Sialk people made small drills or pins of +hammered copper. Thus the metallurgist’s specialized craft had made its +appearance. + +There is at least one very early Iranian site on the inward slopes +of the hilly-flanks zone. It is the earlier of two mounds at a place +called Bakun, in southwestern Iran; the results of the excavations +there are not yet published and we only know of its coarse and +primitive pottery. I only mention Bakun because it helps us to plot the +extent of the hilly-flanks zone villages on the map. + +The Nile Valley lies beyond the peculiar environmental zone of the +hilly flanks of the crescent, and it is probable that the earliest +village-farming communities in Egypt were established by a few people +who wandered into the Nile delta area from the nuclear area. The +assemblage which is most closely comparable to the catalogue of Hassuna +or Judaidah, for example, is that from little settlements along the +shore of the Fayum lake. The Fayum materials come mainly from grain +bins or silos. Another site, Merimde, in the western part of the Nile +delta, shows the remains of a true village, but it may be slightly +later than the settlement of the Fayum. There are radioactive carbon +“dates” for the Fayum materials at about 4275 B.C. ± 320 years, which +is almost fifteen hundred years later than the determinations suggested +for the Hassunan or Syro-Cilician assemblages. I suspect that this +is a somewhat over-extended indication of the time it took for the +generalized cultural pattern of village-farming community life to +spread from the nuclear area down into Egypt, but as yet we have no way +of testing these matters. + +In this same vein, we have two radioactive carbon dates for an +assemblage from sites near Khartoum in the Sudan, best represented by +the mound called Shaheinab. The Shaheinab catalogue roughly corresponds +to that of the Fayum; the distance between the two places, as the Nile +flows, is roughly 1,500 miles. Thus it took almost a thousand years for +the new way of life to be carried as far south into Africa as Khartoum; +the two Shaheinab “dates” average about 3300 B.C. ± 400 years. + +If the movement was up the Nile (southward), as these dates suggest, +then I suspect that the earliest available village material of middle +Egypt, the so-called Tasian, is also later than that of the Fayum. The +Tasian materials come from a few graves near a village called Deir +Tasa, and I have an uncomfortable feeling that the Tasian “assemblage” +may be mainly an artificial selection of poor examples of objects which +belong in the following range of time. + + +SPREAD IN TIME AND SPACE + +There are now two things we can do; in fact, we have already begun to +do them. We can watch the spread of the new way of life upward through +time in the nuclear area. We can also see how the new way of life +spread outward in space from the nuclear area, as time went on. There +is good archeological evidence that both these processes took place. +For the hill country of northeastern Iraq, in the nuclear area, we +have already noticed how the succession (still with gaps) from Karim +Shahir, through M’lefaat and Jarmo, to Hassuna can be charted (see +chart, p. 111). In the next chapter, we shall continue this charting +and description of what happened in Iraq upward through time. We also +watched traces of the new way of life move through space up the Nile +into Africa, to reach Khartoum in the Sudan some thirty-five hundred +years later than we had seen it at Jarmo or Jericho. We caught glimpses +of it in the Fayum and perhaps at Tasa along the way. + +For the remainder of this chapter, I shall try to suggest briefly for +you the directions taken by the spread of the new way of life from the +nuclear area in the Near East. First, let me make clear again that +I _do not_ believe that the village-farming community way of life +was invented only once and in the Near East. It seems to me that the +evidence is very clear that a separate experiment arose in the New +World. For China, the question of independence or borrowing--in the +appearance of the village-farming community there--is still an open +one. In the last chapter, we noted the probability of an independent +nuclear area in southeastern Asia. Professor Carl Sauer strongly +champions the great importance of this area as _the_ original center +of agricultural pursuits, as a kind of “cradle” of all incipient eras +of the Old World at least. While there is certainly not the slightest +archeological evidence to allow us to go that far, we may easily expect +that an early southeast Asian development would have been felt in +China. However, the appearance of the village-farming community in the +northwest of India, at least, seems to have depended on the earlier +development in the Near East. It is also probable that ideas of the new +way of life moved well beyond Khartoum in Africa. + + +THE SPREAD OF THE VILLAGE-FARMING COMMUNITY WAY OF LIFE INTO EUROPE + +How about Europe? I won’t give you many details. You can easily imagine +that the late prehistoric prelude to European history is a complicated +affair. We all know very well how complicated an area Europe is now, +with its welter of different languages and cultures. Remember, however, +that a great deal of archeology has been done on the late prehistory of +Europe, and very little on that of further Asia and Africa. If we knew +as much about these areas as we do of Europe, I expect we’d find them +just as complicated. + +This much is clear for Europe, as far as the spread of the +village-community way of life is concerned. The general idea and much +of the know-how and the basic tools of food-production moved from the +Near East to Europe. So did the plants and animals which had been +domesticated; they were not naturally at home in Europe, as they were +in western Asia. I do not, of course, mean that there were traveling +salesmen who carried these ideas and things to Europe with a commercial +gleam in their eyes. The process took time, and the ideas and things +must have been passed on from one group of people to the next. There +was also some actual movement of peoples, but we don’t know the size of +the groups that moved. + +The story of the “colonization” of Europe by the first farmers is +thus one of (1) the movement from the eastern Mediterranean lands +of some people who were farmers; (2) the spread of ideas and things +beyond the Near East itself and beyond the paths along which the +“colonists” moved; and (3) the adaptations of the ideas and things +by the indigenous “Forest folk”, about whose “receptiveness” Professor +Mathiassen speaks (p. 97). It is important to note that the resulting +cultures in the new European environment were European, not Near +Eastern. The late Professor Childe remarked that “the peoples of the +West were not slavish imitators; they adapted the gifts from the East +... into a new and organic whole capable of developing on its own +original lines.” + + +THE WAYS TO EUROPE + +Suppose we want to follow the traces of those earliest village-farmers +who did travel from western Asia into Europe. Let us start from +Syro-Cilicia, that part of the hilly-flanks zone proper which lies in +the very northeastern corner of the Mediterranean. Three ways would be +open to us (of course we could not be worried about permission from the +Soviet authorities!). We would go north, or north and slightly east, +across Anatolian Turkey, and skirt along either shore of the Black Sea +or even to the east of the Caucasus Mountains along the Caspian Sea, +to reach the plains of Ukrainian Russia. From here, we could march +across eastern Europe to the Baltic and Scandinavia, or even hook back +southwestward to Atlantic Europe. + +Our second way from Syro-Cilicia would also lie over Anatolia, to the +northwest, where we would have to swim or raft ourselves over the +Dardanelles or the Bosphorus to the European shore. Then we would bear +left toward Greece, but some of us might turn right again in Macedonia, +going up the valley of the Vardar River to its divide and on down +the valley of the Morava beyond, to reach the Danube near Belgrade +in Jugoslavia. Here we would turn left, following the great river +valley of the Danube up into central Europe. We would have a number of +tributary valleys to explore, or we could cross the divide and go down +the valley of the Rhine to the North Sea. + +Our third way from Syro-Cilicia would be by sea. We would coast along +southern Anatolia and visit Cyprus, Crete, and the Aegean islands on +our way to Greece, where, in the north, we might meet some of those who +had taken the second route. From Greece, we would sail on to Italy and +the western isles, to reach southern France and the coasts of Spain. +Eventually a few of us would sail up the Atlantic coast of Europe, to +reach western Britain and even Ireland. + +[Illustration: PROBABLE ROUTES AND TIMING IN THE SPREAD OF THE +VILLAGE-FARMING COMMUNITY WAY OF LIFE FROM THE NEAR EAST TO EUROPE] + +Of course none of us could ever take these journeys as the first +farmers took them, since the whole course of each journey must have +lasted many lifetimes. The date given to the assemblage called Windmill +Hill, the earliest known trace of village-farming communities in +England, is about 2500 B.C. I would expect about 5500 B.C. to be a +safe date to give for the well-developed early village communities of +Syro-Cilicia. We suspect that the spread throughout Europe did not +proceed at an even rate. Professor Piggott writes that “at a date +probably about 2600 B.C., simple agricultural communities were being +established in Spain and southern France, and from the latter region a +spread northwards can be traced ... from points on the French seaboard +of the [English] Channel ... there were emigrations of a certain number +of these tribes by boat, across to the chalk lands of Wessex and Sussex +[in England], probably not more than three or four generations later +than the formation of the south French colonies.” + +New radiocarbon determinations are becoming available all the +time--already several suggest that the food-producing way of life +had reached the lower Rhine and Holland by 4000 B.C. But not all +prehistorians accept these “dates,” so I do not show them on my map +(p. 139). + + +THE EARLIEST FARMERS OF ENGLAND + +To describe the later prehistory of all Europe for you would take +another book and a much larger one than this is. Therefore, I have +decided to give you only a few impressions of the later prehistory of +Britain. Of course the British Isles lie at the other end of Europe +from our base-line in western Asia. Also, they received influences +along at least two of the three ways in which the new way of life +moved into Europe. We will look at more of their late prehistory in a +following chapter: here, I shall speak only of the first farmers. + +The assemblage called Windmill Hill, which appears in the south of +England, exhibits three different kinds of structures, evidence of +grain-growing and of stock-breeding, and some distinctive types of +pottery and stone implements. The most remarkable type of structure +is the earthwork enclosures which seem to have served as seasonal +cattle corrals. These enclosures were roughly circular, reached over +a thousand feet in diameter, and sometimes included two or three +concentric sets of banks and ditches. Traces of oblong timber houses +have been found, but not within the enclosures. The second type of +structure is mine-shafts, dug down into the chalk beds where good +flint for the making of axes or hoes could be found. The third type +of structure is long simple mounds or “unchambered barrows,” in one +end of which burials were made. It has been commonly believed that the +Windmill Hill assemblage belonged entirely to the cultural tradition +which moved up through France to the Channel. Professor Piggott is now +convinced, however, that important elements of Windmill Hill stem from +northern Germany and Denmark--products of the first way into Europe +from the east. + +The archeological traces of a second early culture are to be found +in the west of England, western and northern Scotland, and most of +Ireland. The bearers of this culture had come up the Atlantic coast +by sea from southern France and Spain. The evidence they have left us +consists mainly of tombs and the contents of tombs, with only very +rare settlement sites. The tombs were of some size and received the +bodies of many people. The tombs themselves were built of stone, heaped +over with earth; the stones enclosed a passage to a central chamber +(“passage graves”), or to a simple long gallery, along the sides of +which the bodies were laid (“gallery graves”). The general type of +construction is called “megalithic” (= great stone), and the whole +earth-mounded structure is often called a _barrow_. Since many have +proper chambers, in one sense or another, we used the term “unchambered +barrow” above to distinguish those of the Windmill Hill type from these +megalithic structures. There is some evidence for sacrifice, libations, +and ceremonial fires, and it is clear that some form of community +ritual was focused on the megalithic tombs. + +The cultures of the people who produced the Windmill Hill assemblage +and of those who made the megalithic tombs flourished, at least in +part, at the same time. Although the distributions of the two different +types of archeological traces are in quite different parts of the +country, there is Windmill Hill pottery in some of the megalithic +tombs. But the tombs also contain pottery which seems to have arrived +with the tomb builders themselves. + +The third early British group of antiquities of this general time +(following 2500 B.C.) comes from sites in southern and eastern England. +It is not so certain that the people who made this assemblage, called +Peterborough, were actually farmers. While they may on occasion have +practiced a simple agriculture, many items of their assemblage link +them closely with that of the “Forest folk” of earlier times in +England and in the Baltic countries. Their pottery is decorated with +impressions of cords and is quite different from that of Windmill Hill +and the megalithic builders. In addition, the distribution of their +finds extends into eastern Britain, where the other cultures have left +no trace. The Peterborough people had villages with semi-subterranean +huts, and the bones of oxen, pigs, and sheep have been found in a few +of these. On the whole, however, hunting and fishing seem to have been +their vital occupations. They also established trade routes especially +to acquire the raw material for stone axes. + +A probably slightly later culture, whose traces are best known from +Skara Brae on Orkney, also had its roots in those cultures of the +Baltic area which fused out of the meeting of the “Forest folk” and +the peoples who took the eastern way into Europe. Skara Brae is very +well preserved, having been built of thin stone slabs about which +dune-sand drifted after the village died. The individual houses, the +bedsteads, the shelves, the chests for clothes and oddments--all built +of thin stone-slabs--may still be seen in place. But the Skara Brae +people lived entirely by sheep- and cattle-breeding, and by catching +shellfish. Neither grain nor the instruments of agriculture appeared at +Skara Brae. + + +THE EUROPEAN ACHIEVEMENT + +The above is only a very brief description of what went on in Britain +with the arrival of the first farmers. There are many interesting +details which I have omitted in order to shorten the story. + +I believe some of the difficulty we have in understanding the +establishment of the first farming communities in Europe is with +the word “colonization.” We have a natural tendency to think of +“colonization” as it has happened within the last few centuries. In the +case of the colonization of the Americas, for example, the colonists +came relatively quickly, and in increasingly vast numbers. They had +vastly superior technical, political, and war-making skills, compared +with those of the Indians. There was not much mixing with the Indians. +The case in Europe five or six thousand years ago must have been very +different. I wonder if it is even proper to call people “colonists” +who move some miles to a new region, settle down and farm it for some +years, then move on again, generation after generation? The ideas and +the things which these new people carried were only _potentially_ +superior. The ideas and things and the people had to prove themselves +in their adaptation to each new environment. Once this was done another +link to the chain would be added, and then the forest-dwellers and +other indigenous folk of Europe along the way might accept the new +ideas and things. It is quite reasonable to expect that there must have +been much mixture of the migrants and the indigenes along the way; the +Peterborough and Skara Brae assemblages we mentioned above would seem +to be clear traces of such fused cultures. Sometimes, especially if the +migrants were moving by boat, long distances may have been covered in +a short time. Remember, however, we seem to have about three thousand +years between the early Syro-Cilician villages and Windmill Hill. + +Let me repeat Professor Childe again. “The peoples of the West were +not slavish imitators: they adapted the gifts from the East ... into +a new and organic whole capable of developing on its own original +lines.” Childe is of course completely conscious of the fact that his +“peoples of the West” were in part the descendants of migrants who came +originally from the “East,” bringing their “gifts” with them. This +was the late prehistoric achievement of Europe--to take new ideas and +things and some migrant peoples and, by mixing them with the old in its +own environments, to forge a new and unique series of cultures. + +What we know of the ways of men suggests to us that when the details +of the later prehistory of further Asia and Africa are learned, their +stories will be just as exciting. + + + + +THE Conquest of Civilization + +[Illustration] + + +Now we must return to the Near East again. We are coming to the point +where history is about to begin. I am going to stick pretty close +to Iraq and Egypt in this chapter. These countries will perhaps be +the most interesting to most of us, for the foundations of western +civilization were laid in the river lands of the Tigris and Euphrates +and of the Nile. I shall probably stick closest of all to Iraq, because +things first happened there and also because I know it best. + +There is another interesting thing, too. We have seen that the first +experiment in village-farming took place in the Near East. So did +the first experiment in civilization. Both experiments “took.” The +traditions we live by today are based, ultimately, on those ancient +beginnings in food-production and civilization in the Near East. + + +WHAT “CIVILIZATION” MEANS + +I shall not try to define “civilization” for you; rather, I shall +tell you what the word brings to my mind. To me civilization means +urbanization: the fact that there are cities. It means a formal +political set-up--that there are kings or governing bodies that the +people have set up. It means formal laws--rules of conduct--which the +government (if not the people) believes are necessary. It probably +means that there are formalized projects--roads, harbors, irrigation +canals, and the like--and also some sort of army or police force +to protect them. It means quite new and different art forms. It +also usually means there is writing. (The people of the Andes--the +Incas--had everything which goes to make up a civilization but formal +writing. I can see no reason to say they were not civilized.) Finally, +as the late Professor Redfield reminded us, civilization seems to bring +with it the dawn of a new kind of moral order. + +In different civilizations, there may be important differences in the +way such things as the above are managed. In early civilizations, it is +usual to find religion very closely tied in with government, law, and +so forth. The king may also be a high priest, or he may even be thought +of as a god. The laws are usually thought to have been given to the +people by the gods. The temples are protected just as carefully as the +other projects. + + +CIVILIZATION IMPOSSIBLE WITHOUT FOOD-PRODUCTION + +Civilizations have to be made up of many people. Some of the people +live in the country; some live in very large towns or cities. Classes +of society have begun. There are officials and government people; there +are priests or religious officials; there are merchants and traders; +there are craftsmen, metal-workers, potters, builders, and so on; there +are also farmers, and these are the people who produce the food for the +whole population. It must be obvious that civilization cannot exist +without food-production and that food-production must also be at a +pretty efficient level of village-farming before civilization can even +begin. + +But people can be food-producing without being civilized. In many +parts of the world this is still the case. When the white men first +came to America, the Indians in most parts of this hemisphere were +food-producers. They grew corn, potatoes, tomatoes, squash, and many +other things the white men had never eaten before. But only the Aztecs +of Mexico, the Mayas of Yucatan and Guatemala, and the Incas of the +Andes were civilized. + + +WHY DIDN’T CIVILIZATION COME TO ALL FOOD-PRODUCERS? + +Once you have food-production, even at the well-advanced level of +the village-farming community, what else has to happen before you +get civilization? Many men have asked this question and have failed +to give a full and satisfactory answer. There is probably no _one_ +answer. I shall give you my own idea about how civilization _may_ have +come about in the Near East alone. Remember, it is only a guess--a +putting together of hunches from incomplete evidence. It is _not_ meant +to explain how civilization began in any of the other areas--China, +southeast Asia, the Americas--where other early experiments in +civilization went on. The details in those areas are quite different. +Whether certain general principles hold, for the appearance of any +early civilization, is still an open and very interesting question. + + +WHERE CIVILIZATION FIRST APPEARED IN THE NEAR EAST + +You remember that our earliest village-farming communities lay along +the hilly flanks of a great “crescent.” (See map on p. 125.) +Professor Breasted’s “fertile crescent” emphasized the rich river +valleys of the Nile and the Tigris-Euphrates Rivers. Our hilly-flanks +area of the crescent zone arches up from Egypt through Palestine and +Syria, along southern Turkey into northern Iraq, and down along the +southwestern fringe of Iran. The earliest food-producing villages we +know already existed in this area by about 6750 B.C. (± 200 years). + +Now notice that this hilly-flanks zone does not include southern +Mesopotamia, the alluvial land of the lower Tigris and Euphrates in +Iraq, or the Nile Valley proper. The earliest known villages of classic +Mesopotamia and Egypt seem to appear fifteen hundred or more years +after those of the hilly-flanks zone. For example, the early Fayum +village which lies near a lake west of the Nile Valley proper (see p. +135) has a radiocarbon date of 4275 B.C. ± 320 years. It was in the +river lands, however, that the immediate beginnings of civilization +were made. + +We know that by about 3200 B.C. the Early Dynastic period had begun +in southern Mesopotamia. The beginnings of writing go back several +hundred years earlier, but we can safely say that civilization had +begun in Mesopotamia by 3200 B.C. In Egypt, the beginning of the First +Dynasty is slightly later, at about 3100 B.C., and writing probably +did not appear much earlier. There is no question but that history and +civilization were well under way in both Mesopotamia and Egypt by 3000 +B.C.--about five thousand years ago. + + +THE HILLY-FLANKS ZONE VERSUS THE RIVER LANDS + +Why did these two civilizations spring up in these two river +lands which apparently were not even part of the area where the +village-farming community began? Why didn’t we have the first +civilizations in Palestine, Syria, north Iraq, or Iran, where we’re +sure food-production had had a long time to develop? I think the +probable answer gives a clue to the ways in which civilization began in +Egypt and Mesopotamia. + +The land in the hilly flanks is of a sort which people can farm without +too much trouble. There is a fairly fertile coastal strip in Palestine +and Syria. There are pleasant mountain slopes, streams running out to +the sea, and rain, at least in the winter months. The rain belt and the +foothills of the Turkish mountains also extend to northern Iraq and on +to the Iranian plateau. The Iranian plateau has its mountain valleys, +streams, and some rain. These hilly flanks of the “crescent,” through +most of its arc, are almost made-to-order for beginning farmers. The +grassy slopes of the higher hills would be pasture for their herds +and flocks. As soon as the earliest experiments with agriculture and +domestic animals had been successful, a pleasant living could be +made--and without too much trouble. + +I should add here again, that our evidence points increasingly to a +climate for those times which is very little different from that for +the area today. Now look at Egypt and southern Mesopotamia. Both are +lands without rain, for all intents and purposes. Both are lands with +rivers that have laid down very fertile soil--soil perhaps superior to +that in the hilly flanks. But in both lands, the rivers are of no great +aid without some control. + +The Nile floods its banks once a year, in late September or early +October. It not only soaks the narrow fertile strip of land on either +side; it lays down a fresh layer of new soil each year. Beyond the +fertile strip on either side rise great cliffs, and behind them is the +desert. In its natural, uncontrolled state, the yearly flood of the +Nile must have caused short-lived swamps that were full of crocodiles. +After a short time, the flood level would have dropped, the water and +the crocodiles would have run back into the river, and the swamp plants +would have become parched and dry. + +The Tigris and the Euphrates of Mesopotamia are less likely to flood +regularly than the Nile. The Tigris has a shorter and straighter course +than the Euphrates; it is also the more violent river. Its banks are +high, and when the snows melt and flow into all of its tributary rivers +it is swift and dangerous. The Euphrates has a much longer and more +curving course and few important tributaries. Its banks are lower and +it is less likely to flood dangerously. The land on either side and +between the two rivers is very fertile, south of the modern city of +Baghdad. Unlike the Nile Valley, neither the Tigris nor the Euphrates +is flanked by cliffs. The land on either side of the rivers stretches +out for miles and is not much rougher than a poor tennis court. + + +THE RIVERS MUST BE CONTROLLED + +The real trick in both Egypt and Mesopotamia is to make the rivers work +for you. In Egypt, this is a matter of building dikes and reservoirs +that will catch and hold the Nile flood. In this way, the water is held +and allowed to run off over the fields as it is needed. In Mesopotamia, +it is a matter of taking advantage of natural river channels and branch +channels, and of leading ditches from these onto the fields. + +Obviously, we can no longer find the first dikes or reservoirs of +the Nile Valley, or the first canals or ditches of Mesopotamia. The +same land has been lived on far too long for any traces of the first +attempts to be left; or, especially in Egypt, it has been covered by +the yearly deposits of silt, dropped by the river floods. But we’re +pretty sure the first food-producers of Egypt and southern Mesopotamia +must have made such dikes, canals, and ditches. In the first place, +there can’t have been enough rain for them to grow things otherwise. +In the second place, the patterns for such projects seem to have been +pretty well set by historic times. + + +CONTROL OF THE RIVERS THE BUSINESS OF EVERYONE + +Here, then, is a _part_ of the reason why civilization grew in Egypt +and Mesopotamia first--not in Palestine, Syria, or Iran. In the latter +areas, people could manage to produce their food as individuals. It +wasn’t too hard; there were rain and some streams, and good pasturage +for the animals even if a crop or two went wrong. In Egypt and +Mesopotamia, people had to put in a much greater amount of work, and +this work couldn’t be individual work. Whole villages or groups of +people had to turn out to fix dikes or dig ditches. The dikes had to be +repaired and the ditches carefully cleared of silt each year, or they +would become useless. + +There also had to be hard and fast rules. The person who lived nearest +the ditch or the reservoir must not be allowed to take all the water +and leave none for his neighbors. It was not only a business of +learning to control the rivers and of making their waters do the +farmer’s work. It also meant controlling men. But once these men had +managed both kinds of controls, what a wonderful yield they had! The +soil was already fertile, and the silt which came in the floods and +ditches kept adding fertile soil. + + +THE GERM OF CIVILIZATION IN EGYPT AND MESOPOTAMIA + +This learning to work together for the common good was the real germ of +the Egyptian and the Mesopotamian civilizations. The bare elements of +civilization were already there: the need for a governing hand and for +laws to see that the communities’ work was done and that the water was +justly shared. You may object that there is a sort of chicken and egg +paradox in this idea. How could the people set up the rules until they +had managed to get a way to live, and how could they manage to get a +way to live until they had set up the rules? I think that small groups +must have moved down along the mud-flats of the river banks quite +early, making use of naturally favorable spots, and that the rules grew +out of such cases. It would have been like the hand-in-hand growth of +automobiles and paved highways in the United States. + +Once the rules and the know-how did get going, there must have been a +constant interplay of the two. Thus, the more the crops yielded, the +richer and better-fed the people would have been, and the more the +population would have grown. As the population grew, more land would +have needed to be flooded or irrigated, and more complex systems of +dikes, reservoirs, canals, and ditches would have been built. The more +complex the system, the more necessity for work on new projects and for +the control of their use.... And so on.... + +What I have just put down for you is a guess at the manner of growth of +some of the formalized systems that go to make up a civilized society. +My explanation has been pointed particularly at Egypt and Mesopotamia. +I have already told you that the irrigation and water-control part of +it does not apply to the development of the Aztecs or the Mayas, or +perhaps anybody else. But I think that a fair part of the story of +Egypt and Mesopotamia must be as I’ve just told you. + +I am particularly anxious that you do _not_ understand me to mean that +irrigation _caused_ civilization. I am sure it was not that simple at +all. For, in fact, a complex and highly engineered irrigation system +proper did not come until later times. Let’s say rather that the simple +beginnings of irrigation allowed and in fact encouraged a great number +of things in the technological, political, social, and moral realms of +culture. We do not yet understand what all these things were or how +they worked. But without these other aspects of culture, I do not +think that urbanization and civilization itself could have come into +being. + + +THE ARCHEOLOGICAL SEQUENCE TO CIVILIZATION IN IRAQ + +We last spoke of the archeological materials of Iraq on page 130, +where I described the village-farming community of Hassunan type. The +Hassunan type villages appear in the hilly-flanks zone and in the +rolling land adjacent to the Tigris in northern Iraq. It is probable +that even before the Hassuna pattern of culture lived its course, a +new assemblage had been established in northern Iraq and Syria. This +assemblage is called Halaf, after a site high on a tributary of the +Euphrates, on the Syro-Turkish border. + +[Illustration: SKETCH OF SELECTED ITEMS OF HALAFIAN ASSEMBLAGE + + BEADS AND PENDANTS + POTTERY MOTIFS + POTTERY] + +The Halafian assemblage is incompletely known. The culture it +represents included a remarkably handsome painted pottery. +Archeologists have tended to be so fascinated with this pottery that +they have bothered little with the rest of the Halafian assemblage. We +do know that strange stone-founded houses, with plans like those of the +popular notion of an Eskimo igloo, were built. Like the pottery of the +Samarran style, which appears as part of the Hassunan assemblage (see +p. 131), the Halafian painted pottery implies great concentration and +excellence of draftsmanship on the part of the people who painted it. + +We must mention two very interesting sites adjacent to the mud-flats of +the rivers, half way down from northern Iraq to the classic alluvial +Mesopotamian area. One is Baghouz on the Euphrates; the other is +Samarra on the Tigris (see map, p. 125). Both these sites yield the +handsome painted pottery of the style called Samarran: in fact it +is Samarra which gives its name to the pottery. Neither Baghouz nor +Samarra have completely Hassunan types of assemblages, and at Samarra +there are a few pots of proper Halafian style. I suppose that Samarra +and Baghouz give us glimpses of those early farmers who had begun to +finger their way down the mud-flats of the river banks toward the +fertile but yet untilled southland. + + +CLASSIC SOUTHERN MESOPOTAMIA FIRST OCCUPIED + +Our next step is into the southland proper. Here, deep in the core of +the mound which later became the holy Sumerian city of Eridu, Iraqi +archeologists uncovered a handsome painted pottery. Pottery of the same +type had been noticed earlier by German archeologists on the surface +of a small mound, awash in the spring floods, near the remains of the +Biblical city of Erich (Sumerian = Uruk; Arabic = Warka). This “Eridu” +pottery, which is about all we have of the assemblage of the people who +once produced it, may be seen as a blend of the Samarran and Halafian +painted pottery styles. This may over-simplify the case, but as yet we +do not have much evidence to go on. The idea does at least fit with my +interpretation of the meaning of Baghouz and Samarra as way-points on +the mud-flats of the rivers half way down from the north. + +My colleague, Robert Adams, believes that there were certainly +riverine-adapted food-collectors living in lower Mesopotamia. The +presence of such would explain why the Eridu assemblage is not simply +the sum of the Halafian and Samarran assemblages. But the domesticated +plants and animals and the basic ways of food-production must have +come from the hilly-flanks country in the north. + +Above the basal Eridu levels, and at a number of other sites in the +south, comes a full-fledged assemblage called Ubaid. Incidentally, +there is an aspect of the Ubaidian assemblage in the north as well. It +seems to move into place before the Halaf manifestation is finished, +and to blend with it. The Ubaidian assemblage in the south is by far +the more spectacular. The development of the temple has been traced +at Eridu from a simple little structure to a monumental building some +62 feet long, with a pilaster-decorated façade and an altar in its +central chamber. There is painted Ubaidian pottery, but the style is +hurried and somewhat careless and gives the _impression_ of having been +a cheap mass-production means of decoration when compared with the +carefully drafted styles of Samarra and Halaf. The Ubaidian people made +other items of baked clay: sickles and axes of very hard-baked clay +are found. The northern Ubaidian sites have yielded tools of copper, +but metal tools of unquestionable Ubaidian find-spots are not yet +available from the south. Clay figurines of human beings with monstrous +turtle-like faces are another item in the southern Ubaidian assemblage. + +[Illustration: SKETCH OF SELECTED ITEMS OF UBAIDIAN ASSEMBLAGE] + +There is a large Ubaid cemetery at Eridu, much of it still awaiting +excavation. The few skeletons so far tentatively studied reveal a +completely modern type of “Mediterraneanoid”; the individuals whom the +skeletons represent would undoubtedly blend perfectly into the modern +population of southern Iraq. What the Ubaidian assemblage says to us is +that these people had already adapted themselves and their culture to +the peculiar riverine environment of classic southern Mesopotamia. For +example, hard-baked clay axes will chop bundles of reeds very well, or +help a mason dress his unbaked mud bricks, and there were only a few +soft and pithy species of trees available. The Ubaidian levels of Eridu +yield quantities of date pits; that excellent and characteristically +Iraqi fruit was already in use. The excavators also found the clay +model of a ship, with the stepping-point for a mast, so that Sinbad the +Sailor must have had his antecedents as early as the time of Ubaid. +The bones of fish, which must have flourished in the larger canals as +well as in the rivers, are common in the Ubaidian levels and thereafter. + + +THE UBAIDIAN ACHIEVEMENT + +On present evidence, my tendency is to see the Ubaidian assemblage +in southern Iraq as the trace of a new era. I wish there were more +evidence, but what we have suggests this to me. The culture of southern +Ubaid soon became a culture of towns--of centrally located towns with +some rural villages about them. The town had a temple and there must +have been priests. These priests probably had political and economic +functions as well as religious ones, if the somewhat later history of +Mesopotamia may suggest a pattern for us. Presently the temple and its +priesthood were possibly the focus of the market; the temple received +its due, and may already have had its own lands and herds and flocks. +The people of the town, undoubtedly at least in consultation with the +temple administration, planned and maintained the simple irrigation +ditches. As the system flourished, the community of rural farmers would +have produced more than sufficient food. The tendency for specialized +crafts to develop--tentative at best at the cultural level of the +earlier village-farming community era--would now have been achieved, +and probably many other specialists in temple administration, water +control, architecture, and trade would also have appeared, as the +surplus food-supply was assured. + +Southern Mesopotamia is not a land rich in natural resources other +than its fertile soil. Stone, good wood for construction, metal, and +innumerable other things would have had to be imported. Grain and +dates--although both are bulky and difficult to transport--and wool and +woven stuffs must have been the mediums of exchange. Over what area did +the trading net-work of Ubaid extend? We start with the idea that the +Ubaidian assemblage is most richly developed in the south. We assume, I +think, correctly, that it represents a cultural flowering of the south. +On the basis of the pottery of the still elusive “Eridu” immigrants +who had first followed the rivers into alluvial Mesopotamia, we get +the notion that the characteristic painted pottery style of Ubaid +was developed in the southland. If this reconstruction is correct +then we may watch with interest where the Ubaid pottery-painting +tradition spread. We have already mentioned that there is a substantial +assemblage of (and from the southern point of view, _fairly_ pure) +Ubaidian material in northern Iraq. The pottery appears all along the +Iranian flanks, even well east of the head of the Persian Gulf, and +ends in a later and spectacular flourish in an extremely handsome +painted style called the “Susa” style. Ubaidian pottery has been noted +up the valleys of both of the great rivers, well north of the Iraqi +and Syrian borders on the southern flanks of the Anatolian plateau. +It reaches the Mediterranean Sea and the valley of the Orontes in +Syria, and it may be faintly reflected in the painted style of a +site called Ghassul, on the east bank of the Jordan in the Dead Sea +Valley. Over this vast area--certainly in all of the great basin of +the Tigris-Euphrates drainage system and its natural extensions--I +believe we may lay our fingers on the traces of a peculiar way of +decorating pottery, which we call Ubaidian. This cursive and even +slap-dash decoration, it appears to me, was part of a new cultural +tradition which arose from the adjustments which immigrant northern +farmers first made to the new and challenging environment of southern +Mesopotamia. But exciting as the idea of the spread of influences of +the Ubaid tradition in space may be, I believe you will agree that the +consequences of the growth of that tradition in southern Mesopotamia +itself, as time passed, are even more important. + + +THE WARKA PHASE IN THE SOUTH + +So far, there are only two radiocarbon determinations for the Ubaidian +assemblage, one from Tepe Gawra in the north and one from Warka in the +south. My hunch would be to use the dates 4500 to 3750 B.C., with a +plus or more probably a minus factor of about two hundred years for +each, as the time duration of the Ubaidian assemblage in southern +Mesopotamia. + +Next, much to our annoyance, we have what is almost a temporary +black-out. According to the system of terminology I favor, our next +“assemblage” after that of Ubaid is called the _Warka_ phase, from +the Arabic name for the site of Uruk or Erich. We know it only from +six or seven levels in a narrow test-pit at Warka, and from an even +smaller hole at another site. This “assemblage,” so far, is known only +by its pottery, some of which still bears Ubaidian style painting. The +characteristic Warkan pottery is unpainted, with smoothed red or gray +surfaces and peculiar shapes. Unquestionably, there must be a great +deal more to say about the Warkan assemblage, but someone will first +have to excavate it! + + +THE DAWN OF CIVILIZATION + +After our exasperation with the almost unknown Warka interlude, +following the brilliant “false dawn” of Ubaid, we move next to an +assemblage which yields traces of a preponderance of those elements +which we noted (p. 144) as meaning civilization. This assemblage +is that called _Proto-Literate_; it already contains writing. On +the somewhat shaky principle that writing, however early, means +history--and no longer prehistory--the assemblage is named for the +historical implications of its content, and no longer after the name of +the site where it was first found. Since some of the older books used +site-names for this assemblage, I will tell you that the Proto-Literate +includes the latter half of what used to be called the “Uruk period” +_plus_ all of what used to be called the “Jemdet Nasr period.” It shows +a consistent development from beginning to end. + +I shall, in fact, leave much of the description and the historic +implications of the Proto-Literate assemblage to the conventional +historians. Professor T. J. Jacobsen, reaching backward from the +legends he finds in the cuneiform writings of slightly later times, can +in fact tell you a more complete story of Proto-Literate culture than +I can. It should be enough here if I sum up briefly what the excavated +archeological evidence shows. + +We have yet to dig a Proto-Literate site in its entirety, but the +indications are that the sites cover areas the size of small cities. +In architecture, we know of large and monumental temple structures, +which were built on elaborate high terraces. The plans and decoration +of these temples follow the pattern set in the Ubaid phase: the chief +difference is one of size. The German excavators at the site of Warka +reckoned that the construction of only one of the Proto-Literate temple +complexes there must have taken 1,500 men, each working a ten-hour day, +five years to build. + + +ART AND WRITING + +If the architecture, even in its monumental forms, can be seen to +stem from Ubaidian developments, this is not so with our other +evidence of Proto-Literate artistic expression. In relief and applied +sculpture, in sculpture in the round, and on the engraved cylinder +seals--all of which now make their appearance--several completely +new artistic principles are apparent. These include the composition +of subject-matter in groups, commemorative scenes, and especially +the ability and apparent desire to render the human form and face. +Excellent as the animals of the Franco-Cantabrian art may have been +(see p. 85), and however handsome were the carefully drafted +geometric designs and conventionalized figures on the pottery of the +early farmers, there seems to have been, up to this time, a mental +block about the drawing of the human figure and especially the human +face. We do not yet know what caused this self-consciousness about +picturing themselves which seems characteristic of men before the +appearance of civilization. We do know that with civilization, the +mental block seems to have been removed. + +Clay tablets bearing pictographic signs are the Proto-Literate +forerunners of cuneiform writing. The earliest examples are not well +understood but they seem to be “devices for making accounts and +for remembering accounts.” Different from the later case in Egypt, +where writing appears fully formed in the earliest examples, the +development from simple pictographic signs to proper cuneiform writing +may be traced, step by step, in Mesopotamia. It is most probable +that the development of writing was connected with the temple and +the need for keeping account of the temple’s possessions. Professor +Jacobsen sees writing as a means for overcoming space, time, and the +increasing complications of human affairs: “Literacy, which began +with ... civilization, enhanced mightily those very tendencies in its +development which characterize it as a civilization and mark it off as +such from other types of culture.” + +[Illustration: RELIEF ON A PROTO-LITERATE STONE VASE, WARKA + +Unrolled drawing, with restoration suggested by figures from +contemporary cylinder seals] + +While the new principles in art and the idea of writing are not +foreshadowed in the Ubaid phase, or in what little we know of the +Warkan, I do not think we need to look outside southern Mesopotamia +for their beginnings. We do know something of the adjacent areas, +too, and these beginnings are not there. I think we must accept them +as completely new discoveries, made by the people who were developing +the whole new culture pattern of classic southern Mesopotamia. Full +description of the art, architecture, and writing of the Proto-Literate +phase would call for many details. Men like Professor Jacobsen and Dr. +Adams can give you these details much better than I can. Nor shall I do +more than tell you that the common pottery of the Proto-Literate phase +was so well standardized that it looks factory made. There was also +some handsome painted pottery, and there were stone bowls with inlaid +decoration. Well-made tools in metal had by now become fairly common, +and the metallurgist was experimenting with the casting process. Signs +for plows have been identified in the early pictographs, and a wheeled +chariot is shown on a cylinder seal engraving. But if I were forced to +a guess in the matter, I would say that the development of plows and +draft-animals probably began in the Ubaid period and was another of the +great innovations of that time. + +The Proto-Literate assemblage clearly suggests a highly developed and +sophisticated culture. While perhaps not yet fully urban, it is on +the threshold of urbanization. There seems to have been a very dense +settlement of Proto-Literate sites in classic southern Mesopotamia, +many of them newly founded on virgin soil where no earlier settlements +had been. When we think for a moment of what all this implies, of the +growth of an irrigation system which must have existed to allow the +flourish of this culture, and of the social and political organization +necessary to maintain the irrigation system, I think we will agree that +at last we are dealing with civilization proper. + + +FROM PREHISTORY TO HISTORY + +Now it is time for the conventional ancient historians to take over +the story from me. Remember this when you read what they write. Their +real base-line is with cultures ruled over by later kings and emperors, +whose writings describe military campaigns and the administration of +laws and fully organized trading ventures. To these historians, the +Proto-Literate phase is still a simple beginning for what is to follow. +If they mention the Ubaid assemblage at all--the one I was so lyrical +about--it will be as some dim and fumbling step on the path to the +civilized way of life. + +I suppose you could say that the difference in the approach is that as +a prehistorian I have been looking forward or upward in time, while the +historians look backward to glimpse what I’ve been describing here. My +base-line was half a million years ago with a being who had little more +than the capacity to make tools and fire to distinguish him from the +animals about him. Thus my point of view and that of the conventional +historian are bound to be different. You will need both if you want to +understand all of the story of men, as they lived through time to the +present. + + + + +End of PREHISTORY + +[Illustration] + + +You’ll doubtless easily recall your general course in ancient history: +how the Sumerian dynasties of Mesopotamia were supplanted by those of +Babylonia, how the Hittite kingdom appeared in Anatolian Turkey, and +about the three great phases of Egyptian history. The literate kingdom +of Crete arose, and by 1500 B.C. there were splendid fortified Mycenean +towns on the mainland of Greece. This was the time--about the whole +eastern end of the Mediterranean--of what Professor Breasted called the +“first great internationalism,” with flourishing trade, international +treaties, and royal marriages between Egyptians, Babylonians, and +Hittites. By 1200 B.C., the whole thing had fragmented: “the peoples of +the sea were restless in their isles,” and the great ancient centers in +Egypt, Mesopotamia, and Anatolia were eclipsed. Numerous smaller states +arose--Assyria, Phoenicia, Israel--and the Trojan war was fought. +Finally Assyria became the paramount power of all the Near East, +presently to be replaced by Persia. + +A new culture, partaking of older west Asiatic and Egyptian elements, +but casting them with its own tradition into a new mould, arose in +mainland Greece. + +I once shocked my Classical colleagues to the core by referring to +Greece as “a second degree derived civilization,” but there is much +truth in this. The principles of bronze- and then of iron-working, of +the alphabet, and of many other elements in Greek culture were borrowed +from western Asia. Our debt to the Greeks is too well known for me even +to mention it, beyond recalling to you that it is to Greece we owe the +beginnings of rational or empirical science and thought in general. But +Greece fell in its turn to Rome, and in 55 B.C. Caesar invaded Britain. + +I last spoke of Britain on page 142; I had chosen it as my single +example for telling you something of how the earliest farming +communities were established in Europe. Now I will continue with +Britain’s later prehistory, so you may sense something of the end of +prehistory itself. Remember that Britain is simply a single example +we select; the same thing could be done for all the other countries +of Europe, and will be possible also, some day, for further Asia and +Africa. Remember, too, that prehistory in most of Europe runs on for +three thousand or more years _after_ conventional ancient history +begins in the Near East. Britain is a good example to use in showing +how prehistory ended in Europe. As we said earlier, it lies at the +opposite end of Europe from the area of highest cultural achievement in +those times, and should you care to read more of the story in detail, +you may do so in the English language. + + +METAL USERS REACH ENGLAND + +We left the story of Britain with the peoples who made three different +assemblages--the Windmill Hill, the megalith-builders, and the +Peterborough--making adjustments to their environments, to the original +inhabitants of the island, and to each other. They had first arrived +about 2500 B.C., and were simple pastoralists and hoe cultivators who +lived in little village communities. Some of them planted little if any +grain. By 2000 B.C., they were well settled in. Then, somewhere in the +range from about 1900 to 1800 B.C., the traces of the invasion of a new +series of peoples began to appear. + +The first newcomers are called the Beaker folk, after the name of a +peculiar form of pottery they made. The beaker type of pottery seems +oldest in Spain, where it occurs with great collective tombs of +megalithic construction and with copper tools. But the Beaker folk who +reached England seem already to have moved first from Spain(?) to the +Rhineland and Holland. While in the Rhineland, and before leaving for +England, the Beaker folk seem to have mixed with the local population +and also with incomers from northeastern Europe whose culture included +elements brought originally from the Near East by the eastern way +through the steppes. This last group has also been named for a peculiar +article in its assemblage; the group is called the Battle-axe folk. A +few Battle-axe folk elements, including, in fact, stone battle-axes, +reached England with the earliest Beaker folk,[6] coming from the +Rhineland. + + [6] The British authors use the term “Beaker folk” to mean both + archeological assemblage and human physical type. They speak + of a “... tall, heavy-boned, rugged, and round-headed” strain + which they take to have developed, apparently in the Rhineland, + by a mixture of the original (Spanish?) beaker-makers and + the northeast European battle-axe makers. However, since the + science of physical anthropology is very much in flux at the + moment, and since I am not able to assess the evidence for these + physical types, I _do not_ use the term “folk” in this book with + its usual meaning of standardized physical type. When I use + “folk” here, I mean simply _the makers of a given archeological + assemblage_. The difficulty only comes when assemblages are + named for some item in them; it is too clumsy to make an + adjective of the item and refer to a “beakerian” assemblage. + +The Beaker folk settled earliest in the agriculturally fertile south +and east. There seem to have been several phases of Beaker folk +invasions, and it is not clear whether these all came strictly from the +Rhineland or Holland. We do know that their copper daggers and awls +and armlets are more of Irish or Atlantic European than of Rhineland +origin. A few simple habitation sites and many burials of the Beaker +folk are known. They buried their dead singly, sometimes in conspicuous +individual barrows with the dead warrior in his full trappings. The +spectacular element in the assemblage of the Beaker folk is a group +of large circular monuments with ditches and with uprights of wood or +stone. These “henges” became truly monumental several hundred years +later; while they were occasionally dedicated with a burial, they were +not primarily tombs. The effect of the invasion of the Beaker folk +seems to cut across the whole fabric of life in Britain. + +[Illustration: BEAKER] + +There was, however, a second major element in British life at this +time. It shows itself in the less well understood traces of a group +again called after one of the items in their catalogue, the Food-vessel +folk. There are many burials in these “food-vessel” pots in northern +England, Scotland, and Ireland, and the pottery itself seems to +link back to that of the Peterborough assemblage. Like the earlier +Peterborough people in the highland zone before them, the makers of +the food-vessels seem to have been heavily involved in trade. It is +quite proper to wonder whether the food-vessel pottery itself was made +by local women who were married to traders who were middlemen in the +transmission of Irish metal objects to north Germany and Scandinavia. +The belt of high, relatively woodless country, from southwest to +northeast, was already established as a natural route for inland trade. + + +MORE INVASIONS + +About 1500 B.C., the situation became further complicated by the +arrival of new people in the region of southern England anciently +called Wessex. The traces suggest the Brittany coast of France as a +source, and the people seem at first to have been a small but “heroic” +group of aristocrats. Their “heroes” are buried with wealth and +ceremony, surrounded by their axes and daggers of bronze, their gold +ornaments, and amber and jet beads. These rich finds show that the +trade-linkage these warriors patronized spread from the Baltic sources +of amber to Mycenean Greece or even Egypt, as evidenced by glazed blue +beads. + +The great visual trace of Wessex achievement is the final form of +the spectacular sanctuary at Stonehenge. A wooden henge or circular +monument was first made several hundred years earlier, but the site +now received its great circles of stone uprights and lintels. The +diameter of the surrounding ditch at Stonehenge is about 350 feet, the +diameter of the inner circle of large stones is about 100 feet, and +the tallest stone of the innermost horseshoe-shaped enclosure is 29 +feet 8 inches high. One circle is made of blue stones which must have +been transported from Pembrokeshire, 145 miles away as the crow flies. +Recently, many carvings representing the profile of a standard type of +bronze axe of the time, and several profiles of bronze daggers--one of +which has been called Mycenean in type--have been found carved in the +stones. We cannot, of course, describe the details of the religious +ceremonies which must have been staged in Stonehenge, but we can +certainly imagine the well-integrated and smoothly working culture +which must have been necessary before such a great monument could have +been built. + + +“THIS ENGLAND” + +The range from 1900 to about 1400 B.C. includes the time of development +of the archeological features usually called the “Early Bronze Age” +in Britain. In fact, traces of the Wessex warriors persisted down to +about 1200 B.C. The main regions of the island were populated, and the +adjustments to the highland and lowland zones were distinct and well +marked. The different aspects of the assemblages of the Beaker folk and +the clearly expressed activities of the Food-vessel folk and the Wessex +warriors show that Britain was already taking on her characteristic +trading role, separated from the European continent but conveniently +adjacent to it. The tin of Cornwall--so important in the production +of good bronze--as well as the copper of the west and of Ireland, +taken with the gold of Ireland and the general excellence of Irish +metal work, assured Britain a trader’s place in the then known world. +Contacts with the eastern Mediterranean may have been by sea, with +Cornish tin as the attraction, or may have been made by the Food-vessel +middlemen on their trips to the Baltic coast. There they would have +encountered traders who traveled the great north-south European road, +by which Baltic amber moved southward to Greece and the Levant, and +ideas and things moved northward again. + +There was, however, the Channel between England and Europe, and this +relative isolation gave some peace and also gave time for a leveling +and further fusion of culture. The separate cultural traditions began +to have more in common. The growing of barley, the herding of sheep and +cattle, and the production of woolen garments were already features +common to all Britain’s inhabitants save a few in the remote highlands, +the far north, and the distant islands not yet fully touched by +food-production. The “personality of Britain” was being formed. + + +CREMATION BURIALS BEGIN + +Along with people of certain religious faiths, archeologists are +against cremation (for other people!). Individuals to be cremated seem +in past times to have been dressed in their trappings and put upon a +large pyre: it takes a lot of wood and a very hot fire for a thorough +cremation. When the burning had been completed, the few fragile scraps +of bone and such odd beads of stone or other rare items as had resisted +the great heat seem to have been whisked into a pot and the pot buried. +The archeologist is left with the pot and the unsatisfactory scraps in +it. + +Tentatively, after about 1400 B.C. and almost completely over the whole +island by 1200 B.C., Britain became the scene of cremation burials +in urns. We know very little of the people themselves. None of their +settlements have been identified, although there is evidence that they +grew barley and made enclosures for cattle. The urns used for the +burials seem to have antecedents in the pottery of the Food-vessel +folk, and there are some other links with earlier British traditions. +In Lancashire, a wooden circle seems to have been built about a grave +with cremated burials in urns. Even occasional instances of cremation +may be noticed earlier in Britain, and it is not clear what, if any, +connection the British cremation burials in urns have with the classic +_Urnfields_ which were now beginning in the east Mediterranean and +which we shall mention below. + +The British cremation-burial-in-urns folk survived a long time in the +highland zone. In the general British scheme, they make up what is +called the “Middle Bronze Age,” but in the highland zone they last +until after 900 B.C. and are considered to be a specialized highland +“Late Bronze Age.” In the highland zone, these later cremation-burial +folk seem to have continued the older Food-vessel tradition of being +middlemen in the metal market. + +Granting that our knowledge of this phase of British prehistory is +very restricted because the cremations have left so little for the +archeologist, it does not appear that the cremation-burial-urn folk can +be sharply set off from their immediate predecessors. But change on a +grander scale was on the way. + + +REVERBERATIONS FROM CENTRAL EUROPE + +In the centuries immediately following 1000 B.C., we see with fair +clarity two phases of a cultural process which must have been going +on for some time. Certainly several of the invasions we have already +described in this chapter were due to earlier phases of the same +cultural process, but we could not see the details. + +[Illustration: SLASHING SWORD] + +Around 1200 B.C. central Europe was upset by the spread of the +so-called Urnfield folk, who practiced cremation burial in urns and +whom we also know to have been possessors of long, slashing swords and +the horse. I told you above that we have no idea that the Urnfield +folk proper were in any way connected with the people who made +cremation-burial-urn cemeteries a century or so earlier in Britain. It +has been supposed that the Urnfield folk themselves may have shared +ideas with the people who sacked Troy. We know that the Urnfield +pressure from central Europe displaced other people in northern France, +and perhaps in northwestern Germany, and that this reverberated into +Britain about 1000 B.C. + +Soon after 750 B.C., the same thing happened again. This time, the +pressure from central Europe came from the Hallstatt folk who were iron +tool makers: the reverberation brought people from the western Alpine +region across the Channel into Britain. + +At first it is possible to see the separate results of these folk +movements, but the developing cultures soon fused with each other and +with earlier British elements. Presently there were also strains of +other northern and western European pottery and traces of Urnfield +practices themselves which appeared in the finished British product. I +hope you will sense that I am vastly over-simplifying the details. + +The result seems to have been--among other things--a new kind of +agricultural system. The land was marked off by ditched divisions. +Rectangular fields imply the plow rather than hoe cultivation. We seem +to get a picture of estate or tribal boundaries which included village +communities; we find a variety of tools in bronze, and even whetstones +which show that iron has been honed on them (although the scarce iron +has not been found). Let me give you the picture in Professor S. +Piggott’s words: “The ... Late Bronze Age of southern England was but +the forerunner of the earliest Iron Age in the same region, not only in +the techniques of agriculture, but almost certainly in terms of ethnic +kinship ... we can with some assurance talk of the Celts ... the great +early Celtic expansion of the Continent is recognized to be that of the +Urnfield people.” + +Thus, certainly by 500 B.C., there were people in Britain, some of +whose descendants we may recognize today in name or language in remote +parts of Wales, Scotland, and the Hebrides. + + +THE COMING OF IRON + +Iron--once the know-how of reducing it from its ore in a very hot, +closed fire has been achieved--produces a far cheaper and much more +efficient set of tools than does bronze. Iron tools seem first to +have been made in quantity in Hittite Anatolia about 1500 B.C. In +continental Europe, the earliest, so-called Hallstatt, iron-using +cultures appeared in Germany soon after 750 B.C. Somewhat later, +Greek and especially Etruscan exports of _objets d’art_--which moved +with a flourishing trans-Alpine wine trade--influenced the Hallstatt +iron-working tradition. Still later new classical motifs, together with +older Hallstatt, oriental, and northern nomad motifs, gave rise to a +new style in metal decoration which characterizes the so-called La Tène +phase. + +A few iron users reached Britain a little before 400 B.C. Not long +after that, a number of allied groups appeared in southern and +southeastern England. They came over the Channel from France and must +have been Celts with dialects related to those already in England. A +second wave of Celts arrived from the Marne district in France about +250 B.C. Finally, in the second quarter of the first century B.C., +there were several groups of newcomers, some of whom were Belgae of +a mixed Teutonic-Celtic confederacy of tribes in northern France and +Belgium. The Belgae preceded the Romans by only a few years. + + +HILL-FORTS AND FARMS + +The earliest iron-users seem to have entrenched themselves temporarily +within hill-top forts, mainly in the south. Gradually, they moved +inland, establishing _individual_ farm sites with extensive systems +of rectangular fields. We recognize these fields by the “lynchets” or +lines of soil-creep which plowing left on the slopes of hills. New +crops appeared; there were now bread wheat, oats, and rye, as well as +barley. + +At Little Woodbury, near the town of Salisbury, a farmstead has been +rather completely excavated. The rustic buildings were within a +palisade, the round house itself was built of wood, and there were +various outbuildings and pits for the storage of grain. Weaving was +done on the farm, but not blacksmithing, which must have been a +specialized trade. Save for the lack of firearms, the place might +almost be taken for a farmstead on the American frontier in the early +1800’s. + +Toward 250 B.C. there seems to have been a hasty attempt to repair the +hill-forts and to build new ones, evidently in response to signs of +restlessness being shown by remote relatives in France. + + +THE SECOND PHASE + +Perhaps the hill-forts were not entirely effective or perhaps a +compromise was reached. In any case, the newcomers from the Marne +district did establish themselves, first in the southeast and then to +the north and west. They brought iron with decoration of the La Tène +type and also the two-wheeled chariot. Like the Wessex warriors of +over a thousand years earlier, they made “heroes’” graves, with their +warriors buried in the war-chariots and dressed in full trappings. + +[Illustration: CELTIC BUCKLE] + +The metal work of these Marnian newcomers is excellent. The peculiar +Celtic art style, based originally on the classic tendril motif, +is colorful and virile, and fits with Greek and Roman descriptions +of Celtic love of color in dress. There is a strong trace of these +newcomers northward in Yorkshire, linked by Ptolemy’s description to +the Parisii, doubtless part of the Celtic tribe which originally gave +its name to Paris on the Seine. Near Glastonbury, in Somerset, two +villages in swamps have been excavated. They seem to date toward the +middle of the first century B.C., which was a troubled time in Britain. +The circular houses were built on timber platforms surrounded with +palisades. The preservation of antiquities by the water-logged peat of +the swamp has yielded us a long catalogue of the materials of these +villagers. + +In Scotland, which yields its first iron tools at a date of about 100 +B.C., and in northern Ireland even slightly earlier, the effects of the +two phases of newcomers tend especially to blend. Hill-forts, “brochs” +(stone-built round towers) and a variety of other strange structures +seem to appear as the new ideas develop in the comparative isolation of +northern Britain. + + +THE THIRD PHASE + +For the time of about the middle of the first century B.C., we again +see traces of frantic hill-fort construction. This simple military +architecture now took some new forms. Its multiple ramparts must +reflect the use of slings as missiles, rather than spears. We probably +know the reason. In 56 B.C., Julius Caesar chastised the Veneti of +Brittany for outraging the dignity of Roman ambassadors. The Veneti +were famous slingers, and doubtless the reverberations of escaping +Veneti were felt across the Channel. The military architecture suggests +that some Veneti did escape to Britain. + +Also, through Caesar, we learn the names of newcomers who arrived in +two waves, about 75 B.C. and about 50 B.C. These were the Belgae. Now, +at last, we can even begin to speak of dynasties and individuals. +Some time before 55 B.C., the Catuvellauni, originally from the Marne +district in France, had possessed themselves of a large part of +southeastern England. They evidently sailed up the Thames and built a +town of over a hundred acres in area. Here ruled Cassivellaunus, “the +first man in England whose name we know,” and whose town Caesar sacked. +The town sprang up elsewhere again, however. + + +THE END OF PREHISTORY + +Prehistory, strictly speaking, is now over in southern Britain. +Claudius’ effective invasion took place in 43 A.D.; by 83 A.D., a raid +had been made as far north as Aberdeen in Scotland. But by 127 A.D., +Hadrian had completed his wall from the Solway to the Tyne, and the +Romans settled behind it. In Scotland, Romanization can have affected +the countryside very little. Professor Piggott adds that “... it is +when the pressure of Romanization is relaxed by the break-up of the +Dark Ages that we see again the Celtic metal-smiths handling their +material with the same consummate skill as they had before the Roman +Conquest, and with traditional styles that had not even then forgotten +their Marnian and Belgic heritage.” + +In fact, many centuries go by, in Britain as well as in the rest of +Europe, before the archeologist’s task is complete and the historian on +his own is able to describe the ways of men in the past. + + +BRITAIN AS A SAMPLE OF THE GENERAL COURSE OF PREHISTORY IN EUROPE + +In giving this very brief outline of the later prehistory of Britain, +you will have noticed how often I had to refer to the European +continent itself. Britain, beyond the English Channel for all of her +later prehistory, had a much simpler course of events than did most of +the rest of Europe in later prehistoric times. This holds, in spite +of all the “invasions” and “reverberations” from the continent. Most +of Europe was the scene of an even more complicated ebb and flow of +cultural change, save in some of its more remote mountain valleys and +peninsulas. + +The whole course of later prehistory in Europe is, in fact, so very +complicated that there is no single good book to cover it all; +certainly there is none in English. There are some good regional +accounts and some good general accounts of part of the range from about +3000 B.C. to A.D. 1. I suspect that the difficulty of making a good +book that covers all of its later prehistory is another aspect of what +makes Europe so very complicated a continent today. The prehistoric +foundations for Europe’s very complicated set of civilizations, +cultures, and sub-cultures--which begin to appear as history +proceeds--were in themselves very complicated. + +Hence, I selected the case of Britain as a single example of how +prehistory ends in Europe. It could have been more complicated than we +found it to be. Even in the subject matter on Britain in the chapter +before the last, we did not see direct traces of the effect on Britain +of the very important developments which took place in the Danubian +way from the Near East. Apparently Britain was not affected. Britain +received the impulses which brought copper, bronze, and iron tools from +an original east Mediterranean homeland into Europe, almost at the ends +of their journeys. But by the same token, they had had time en route to +take on their characteristic European aspects. + +Some time ago, Sir Cyril Fox wrote a famous book called _The +Personality of Britain_, sub-titled “Its Influence on Inhabitant and +Invader in Prehistoric and Early Historic Times.” We have not gone +into the post-Roman early historic period here; there are still the +Anglo-Saxons and Normans to account for as well as the effects of +the Romans. But what I have tried to do was to begin the story of +how the personality of Britain was formed. The principles that Fox +used, in trying to balance cultural and environmental factors and +interrelationships would not be greatly different for other lands. + + + + +Summary + +[Illustration] + + +In the pages you have read so far, you have been brought through the +earliest 99 per cent of the story of man’s life on this planet. I have +left only 1 per cent of the story for the historians to tell. + + +THE DRAMA OF THE PAST + +Men first became men when evolution had carried them to a certain +point. This was the point where the eye-hand-brain co-ordination was +good enough so that tools could be made. When tools began to be made +according to sets of lasting habits, we know that men had appeared. +This happened over a half million years ago. The stage for the play +may have been as broad as all of Europe, Africa, and Asia. At least, +it seems unlikely that it was only one little region that saw the +beginning of the drama. + +Glaciers and different climates came and went, to change the settings. +But the play went on in the same first act for a very long time. The +men who were the players had simple roles. They had to feed themselves +and protect themselves as best they could. They did this by hunting, +catching, and finding food wherever they could, and by taking such +protection as caves, fire, and their simple tools would give them. +Before the first act was over, the last of the glaciers was melting +away, and the players had added the New World to their stage. If +we want a special name for the first act, we could call it _The +Food-Gatherers_. + +There were not many climaxes in the first act, so far as we can see. +But I think there may have been a few. Certainly the pace of the +first act accelerated with the swing from simple gathering to more +intensified collecting. The great cave art of France and Spain was +probably an expression of a climax. Even the ideas of burying the dead +and of the “Venus” figurines must also point to levels of human thought +and activity that were over and above pure food-getting. + + +THE SECOND ACT + +The second act began only about ten thousand years ago. A few of the +players started it by themselves near the center of the Old World part +of the stage, in the Near East. It began as a plant and animal act, but +it soon became much more complicated. + +But the players in this one part of the stage--in the Near East--were +not the only ones to start off on the second act by themselves. Other +players, possibly in several places in the Far East, and certainly in +the New World, also started second acts that began as plant and animal +acts, and then became complicated. We can call the whole second act +_The Food-Producers_. + + +THE FIRST GREAT CLIMAX OF THE SECOND ACT + +In the Near East, the first marked climax of the second act happened +in Mesopotamia and Egypt. The play and the players reached that great +climax that we call civilization. This seems to have come less than +five thousand years after the second act began. But it could never have +happened in the first act at all. + +There is another curious thing about the first act. Many of the players +didn’t know it was over and they kept on with their roles long after +the second act had begun. On the edges of the stage there are today +some players who are still going on with the first act. The Eskimos, +and the native Australians, and certain tribes in the Amazon jungle are +some of these players. They seem perfectly happy to keep on with the +first act. + +The second act moved from climax to climax. The civilizations of +Mesopotamia and Egypt were only the earliest of these climaxes. The +players to the west caught the spirit of the thing, and climaxes +followed there. So also did climaxes come in the Far Eastern and New +World portions of the stage. + +The greater part of the second act should really be described to you +by a historian. Although it was a very short act when compared to the +first one, the climaxes complicate it a great deal. I, a prehistorian, +have told you about only the first act, and the very beginning of the +second. + + +THE THIRD ACT + +Also, as a prehistorian I probably should not even mention the third +act--it began so recently. The third act is _The Industrialization_. +It is the one in which we ourselves are players. If the pace of the +second act was so much faster than that of the first, the pace of the +third act is terrific. The danger is that it may wear down the players +completely. + +What sort of climaxes will the third act have, and are we already in +one? You have seen by now that the acts of my play are given in terms +of modes or basic patterns of human economy--ways in which people +get food and protection and safety. The climaxes involve more than +human economy. Economics and technological factors may be part of the +climaxes, but they are not all. The climaxes may be revolutions in +their own way, intellectual and social revolutions if you like. + +If the third act follows the pattern of the second act, a climax should +come soon after the act begins. We may be due for one soon if we are +not already in it. Remember the terrific pace of this third act. + + +WHY BOTHER WITH PREHISTORY? + +Why do we bother about prehistory? The main reason is that we think it +may point to useful ideas for the present. We are in the troublesome +beginnings of the third act of the play. The beginnings of the second +act may have lessons for us and give depth to our thinking. I know +there are at least _some_ lessons, even in the present incomplete +state of our knowledge. The players who began the second act--that of +food-production--separately, in different parts of the world, were not +all of one “pure race” nor did they have “pure” cultural traditions. +Some apparently quite mixed Mediterraneans got off to the first start +on the second act and brought it to its first two climaxes as well. +Peoples of quite different physical type achieved the first climaxes in +China and in the New World. + +In our British example of how the late prehistory of Europe worked, we +listed a continuous series of “invasions” and “reverberations.” After +each of these came fusion. Even though the Channel protected Britain +from some of the extreme complications of the mixture and fusion of +continental Europe, you can see how silly it would be to refer to a +“pure” British race or a “pure” British culture. We speak of the United +States as a “melting pot.” But this is nothing new. Actually, Britain +and all the rest of the world have been “melting pots” at one time or +another. + +By the time the written records of Mesopotamia and Egypt begin to turn +up in number, the climaxes there are well under way. To understand the +beginnings of the climaxes, and the real beginnings of the second act +itself, we are thrown back on prehistoric archeology. And this is as +true for China, India, Middle America, and the Andes, as it is for the +Near East. + +There are lessons to be learned from all of man’s past, not simply +lessons of how to fight battles or win peace conferences, but of how +human society evolves from one stage to another. Many of these lessons +can only be looked for in the prehistoric past. So far, we have only +made a beginning. There is much still to do, and many gaps in the story +are yet to be filled. The prehistorian’s job is to find the evidence, +to fill the gaps, and to discover the lessons men have learned in the +past. As I see it, this is not only an exciting but a very practical +goal for which to strive. + + + + +List of Books + + +BOOKS OF GENERAL INTEREST + +(Chosen from a variety of the increasingly useful list of cheap +paperbound books.) + + Childe, V. Gordon + _What Happened in History._ 1954. Penguin. + _Man Makes Himself._ 1955. Mentor. + _The Prehistory of European Society._ 1958. Penguin. + + Dunn, L. C., and Dobzhansky, Th. + _Heredity, Race, and Society._ 1952. Mentor. + + Frankfort, Henri, Frankfort, H. A., Jacobsen, Thorkild, and Wilson, + John A. + _Before Philosophy._ 1954. Penguin. + + Simpson, George G. + _The Meaning of Evolution._ 1955. Mentor. + + Wheeler, Sir Mortimer + _Archaeology from the Earth._ 1956. Penguin. + + +GEOCHRONOLOGY AND THE ICE AGE + +(Two general books. Some Pleistocene geologists disagree with Zeuner’s +interpretation of the dating evidence, but their points of view appear +in professional journals, in articles too cumbersome to list here.) + + Flint, R. F. + _Glacial Geology and the Pleistocene Epoch._ 1947. John Wiley + and Sons. + + Zeuner, F. E. + _Dating the Past._ 1952 (3rd ed.). Methuen and Co. + + +FOSSIL MEN AND RACE + +(The points of view of physical anthropologists and human +paleontologists are changing very quickly. Two of the different points +of view are listed here.) + + Clark, W. E. Le Gros + _History of the Primates._ 1956 (5th ed.). British Museum + (Natural History). (Also in Phoenix edition, 1957.) + + Howells, W. W. + _Mankind So Far._ 1944. Doubleday, Doran. + + +GENERAL ANTHROPOLOGY + +(These are standard texts not absolutely up to date in every detail, or +interpretative essays concerned with cultural change through time as +well as in space.) + + Kroeber, A. L. + _Anthropology._ 1948. Harcourt, Brace. + + Linton, Ralph + _The Tree of Culture._ 1955. Alfred A. Knopf, Inc. + + Redfield, Robert + _The Primitive World and Its Transformations._ 1953. Cornell + University Press. + + Steward, Julian H. + _Theory of Culture Change._ 1955. University of Illinois Press. + + White, Leslie + _The Science of Culture._ 1949. Farrar, Strauss. + + +GENERAL PREHISTORY + +(A sampling of the more useful and current standard works in English.) + + Childe, V. Gordon + _The Dawn of European Civilization._ 1957. Kegan Paul, Trench, + Trubner. + _Prehistoric Migrations in Europe._ 1950. Instituttet for + Sammenlignende Kulturforskning. + + Clark, Grahame + _Archaeology and Society._ 1957. Harvard University Press. + + Clark, J. G. D. + _Prehistoric Europe: The Economic Basis._ 1952. Methuen and Co. + + Garrod, D. A. E. + _Environment, Tools, and Man._ 1946. Cambridge University + Press. + + Movius, Hallam L., Jr. + “Old World Prehistory: Paleolithic” in _Anthropology Today_. + Kroeber, A. L., ed. 1953. University of Chicago Press. + + Oakley, Kenneth P. + _Man the Tool-Maker._ 1956. British Museum (Natural History). + (Also in Phoenix edition, 1957.) + + Piggott, Stuart + _British Prehistory._ 1949. Oxford University Press. + + Pittioni, Richard + _Die Urgeschichtlichen Grundlagen der Europäischen Kultur._ + 1949. Deuticke. (A single book which does attempt to cover the + whole range of European prehistory to ca. 1 A.D.) + + +THE NEAR EAST + + Adams, Robert M. + “Developmental Stages in Ancient Mesopotamia,” _in_ Steward, + Julian, _et al_, _Irrigation Civilizations: A Comparative + Study_. 1955. Pan American Union. + + Braidwood, Robert J. + _The Near East and the Foundations for Civilization._ 1952. + University of Oregon. + + Childe, V. Gordon + _New Light on the Most Ancient East._ 1952. Oriental Dept., + Routledge and Kegan Paul. + + Frankfort, Henri + _The Birth of Civilization in the Near East._ 1951. University + of Indiana Press. (Also in Anchor edition, 1956.) + + Pallis, Svend A. + _The Antiquity of Iraq._ 1956. Munksgaard. + + Wilson, John A. + _The Burden of Egypt._ 1951. University of Chicago Press. (Also + in Phoenix edition, called _The Culture of Ancient Egypt_, + 1956.) + + +HOW DIGGING IS DONE + + Braidwood, Linda + _Digging beyond the Tigris._ 1953. Schuman, New York. + + Wheeler, Sir Mortimer + _Archaeology from the Earth._ 1954. Oxford, London. + + + + +Index + + + Abbevillian, 48; + core-biface tool, 44, 48 + + Acheulean, 48, 60 + + Acheuleo-Levalloisian, 63 + + Acheuleo-Mousterian, 63 + + Adams, R. M., 106 + + Adzes, 45 + + Africa, east, 67, 89; + north, 70, 89; + south, 22, 25, 34, 40, 67 + + Agriculture, incipient, in England, 140; + in Near East, 123 + + Ain Hanech, 48 + + Amber, taken from Baltic to Greece, 167 + + American Indians, 90, 142 + + Anatolia, used as route to Europe, 138 + + Animals, in caves, 54, 64; + in cave art, 85 + + Antevs, Ernst, 19 + + Anyathian, 47 + + Archeological interpretation, 8 + + Archeology, defined, 8 + + Architecture, at Jarmo, 128; + at Jericho, 133 + + Arrow, points, 94; + shaft straightener, 83 + + Art, in caves, 84; + East Spanish, 85; + figurines, 84; + Franco-Cantabrian, 84, 85; + movable (engravings, modeling, scratchings), 83; + painting, 83; + sculpture, 83 + + Asia, western, 67 + + Assemblage, defined, 13, 14; + European, 94; + Jarmo, 129; + Maglemosian, 94; + Natufian, 113 + + Aterian, industry, 67; + point, 89 + + Australopithecinae, 24 + + Australopithecine, 25, 26 + + Awls, 77 + + Axes, 62, 94 + + Ax-heads, 15 + + Azilian, 97 + + Aztecs, 145 + + + Baghouz, 152 + + Bakun, 134 + + Baltic sea, 93 + + Banana, 107 + + Barley, wild, 108 + + Barrow, 141 + + Battle-axe folk, 164; + assemblage, 164 + + Beads, 80; + bone, 114 + + Beaker folk, 164; + assemblage, 164-165 + + Bear, in cave art, 85; + cult, 68 + + Belgium, 94 + + Belt cave, 126 + + Bering Strait, used as route to New World, 98 + + Bison, in cave art, 85 + + Blade, awl, 77; + backed, 75; + blade-core, 71; + end-scraper, 77; + stone, defined, 71; + strangulated (notched), 76; + tanged point, 76; + tools, 71, 75-80, 90; + tool tradition, 70 + + Boar, wild, in cave art, 85 + + Bogs, source of archeological materials, 94 + + Bolas, 54 + + Bordes, François, 62 + + Borer, 77 + + Boskop skull, 34 + + Boyd, William C., 35 + + Bracelets, 118 + + Brain, development of, 24 + + Breadfruit, 107 + + Breasted, James H., 107 + + Brick, at Jericho, 133 + + Britain, 94; + late prehistory, 163-175; + invaders, 173 + + Broch, 172 + + Buffalo, in China, 54; + killed by stampede, 86 + + Burials, 66, 86; + in “henges,” 164; + in urns, 168 + + Burins, 75 + + Burma, 90 + + Byblos, 134 + + + Camel, 54 + + Cannibalism, 55 + + Cattle, wild, 85, 112; + in cave art, 85; + domesticated, 15; + at Skara Brae, 142 + + Caucasoids, 34 + + Cave men, 29 + + Caves, 62; + art in, 84 + + Celts, 170 + + Chariot, 160 + + Chicken, domestication of, 107 + + Chiefs, in food-gathering groups, 68 + + Childe, V. Gordon, 8 + + China, 136 + + Choukoutien, 28, 35 + + Choukoutienian, 47 + + Civilization, beginnings, 144, 149, 157; + meaning of, 144 + + Clactonian, 45, 47 + + Clay, used in modeling, 128; + baked, used for tools, 153 + + Club-heads, 82, 94 + + Colonization, in America, 142; + in Europe, 142 + + Combe Capelle, 30 + + Combe Capelle-Brünn group, 34 + + Commont, Victor, 51 + + Coon, Carlton S., 73 + + Copper, 134 + + Corn, in America, 145 + + Corrals for cattle, 140 + + “Cradle of mankind,” 136 + + Cremation, 167 + + Crete, 162 + + Cro-Magnon, 30, 34 + + Cultivation, incipient, 105, 109, 111 + + Culture, change, 99; + characteristics, defined, 38, 49; + prehistoric, 39 + + + Danube Valley, used as route from Asia, 138 + + Dates, 153 + + Deer, 54, 96 + + Dog, domesticated, 96 + + Domestication, of animals, 100, 105, 107; + of plants, 100 + + “Dragon teeth” fossils in China, 28 + + Drill, 77 + + Dubois, Eugene, 26 + + + Early Dynastic Period, Mesopotamia, 147 + + East Spanish art, 72, 85 + + Egypt, 70, 126 + + Ehringsdorf, 31 + + Elephant, 54 + + Emiliani, Cesare, 18 + + Emiran flake point, 73 + + England, 163-168; + prehistoric, 19, 40; + farmers in, 140 + + Eoanthropus dawsoni, 29 + + Eoliths, 41 + + Erich, 152 + + Eridu, 152 + + Euphrates River, floods in, 148 + + Europe, cave dwellings, 58; + at end of Ice Age, 93; + early farmers, 140; + glaciers in, 40; + huts in, 86; + routes into, 137-140; + spread of food-production to, 136 + + + Far East, 69, 90 + + Farmers, 103 + + Fauresmith industry, 67 + + Fayum, 135; + radiocarbon date, 146 + + “Fertile Crescent,” 107, 146 + + Figurines, “Venus,” 84; + at Jarmo, 128; + at Ubaid, 153 + + Fire, used by Peking man, 54 + + First Dynasty, Egypt, 147 + + Fish-hooks, 80, 94 + + Fishing, 80; + by food-producers, 122 + + Fish-lines, 80 + + Fish spears, 94 + + Flint industry, 127 + + Fontéchevade, 32, 56, 58 + + Food-collecting, 104, 121; + end of, 104 + + Food-gatherers, 53, 176 + + Food-gathering, 99, 104; + in Old World, 104; + stages of, 104 + + Food-producers, 176 + + Food-producing economy, 122; + in America, 145; + in Asia, 105 + + Food-producing revolution, 99, 105; + causes of, 101; + preconditions for, 100 + + Food-production, beginnings of, 99; + carried to Europe, 110 + + Food-vessel folk, 164 + + “Forest folk,” 97, 98, 104, 110 + + Fox, Sir Cyril, 174 + + France, caves in, 56 + + + Galley Hill (fossil type), 29 + + Garrod, D. A., 73 + + Gazelle, 114 + + Germany, 94 + + Ghassul, 156 + + Glaciers, 18, 30; + destruction by, 40 + + Goat, wild, 108; + domesticated, 128 + + Grain, first planted, 20 + + Graves, passage, 141; + gallery, 141 + + Greece, civilization in, 163; + as route to western Europe, 138; + towns in, 162 + + Grimaldi skeletons, 34 + + + Hackberry seeds used as food, 55 + + Halaf, 151; + assemblage, 151 + + Hallstatt, tradition, 169 + + Hand, development of, 24, 25 + + Hand adzes, 46 + + Hand axes, 44 + + Harpoons, antler, 83, 94; + bone, 82, 94 + + Hassuna, 131; + assemblage, 131, 132 + + Heidelberg, fossil type, 28 + + Hill-forts, in England, 171; + in Scotland, 172 + + Hilly flanks of Near East, 107, 108, 125, 131, 146, 147 + + History, beginning of, 7, 17 + + Hoes, 112 + + Holland, 164 + + Homo sapiens, 32 + + Hooton, E. A., 34 + + Horse, 112; + wild, in cave art, 85; + in China, 54 + + Hotu cave, 126 + + Houses, 122; + at Jarmo, 128; + at Halaf, 151 + + Howe, Bruce, 116 + + Howell, F. Clark, 30 + + Hunting, 93 + + + Ice Age, in Asia, 99; + beginning of, 18; + glaciers in, 41; + last glaciation, 93 + + Incas, 145 + + India, 90, 136 + + Industrialization, 178 + + Industry, blade-tool, 88; + defined, 58; + ground stone, 94 + + Internationalism, 162 + + Iran, 107, 147 + + Iraq, 107, 124, 127, 136, 147 + + Iron, introduction of, 170 + + Irrigation, 123, 149, 155 + + Italy, 138 + + + Jacobsen, T. J., 157 + + Jarmo, 109, 126, 128, 130; + assemblage, 129 + + Java, 23, 29 + + Java man, 26, 27, 29 + + Jefferson, Thomas, 11 + + Jericho, 119, 133 + + Judaidah, 134 + + + Kafuan, 48 + + Kanam, 23, 36 + + Karim Shahir, 116-119, 124; + assemblage, 116, 117 + + Keith, Sir Arthur, 33 + + Kelley, Harper, 51 + + Kharga, 126 + + Khartoum, 136 + + Knives, 80 + + Krogman, W. M., 3, 25 + + + Lamps, 85 + + Land bridges in Mediterranean, 19 + + La Tène phase, 170 + + Laurel leaf point, 78, 89 + + Leakey, L. S. B., 40 + + Le Moustier, 57 + + Levalloisian, 47, 61, 62 + + Levalloiso-Mousterian, 47, 63 + + Little Woodbury, 170 + + + Magic, used by hunters, 123 + + Maglemosian, assemblage, 94, 95; + folk, 98 + + Makapan, 40 + + Mammoth, 93; + in cave art, 85 + + “Man-apes,” 26 + + Mango, 107 + + Mankind, age, 17 + + Maringer, J., 45 + + Markets, 155 + + Marston, A. T., 11 + + Mathiassen, T., 97 + + McCown, T. D., 33 + + Meganthropus, 26, 27, 36 + + Men, defined, 25; + modern, 32 + + Merimde, 135 + + Mersin, 133 + + Metal-workers, 160, 163, 167, 172 + + Micoquian, 48, 60 + + Microliths, 87; + at Jarmo, 130; + “lunates,” 87; + trapezoids, 87; + triangles, 87 + + Minerals used as coloring matter, 66 + + Mine-shafts, 140 + + M’lefaat, 126, 127 + + Mongoloids, 29, 90 + + Mortars, 114, 118, 127 + + Mounds, how formed, 12 + + Mount Carmel, 11, 33, 52, 59, 64, 69, 113, 114 + + “Mousterian man,” 64 + + “Mousterian” tools, 61, 62; + of Acheulean tradition, 62 + + Movius, H. L., 47 + + + Natufian, animals in, 114; + assemblage, 113, 114, 115; + burials, 114; + date of, 113 + + Neanderthal man, 29, 30, 31, 56 + + Near East, beginnings of civilization in, 20, 144; + cave sites, 58; + climate in Ice Age, 99; + “Fertile Crescent,” 107, 146; + food-production in, 99; + Natufian assemblage in, 113-115; + stone tools, 114 + + Needles, 80 + + Negroid, 34 + + New World, 90 + + Nile River valley, 102, 134; + floods in, 148 + + Nuclear area, 106, 110; + in Near East, 107 + + + Obsidian, used for blade tools, 71; + at Jarmo, 130 + + Ochre, red, with burials, 86 + + Oldowan, 48 + + Old World, 67, 70, 90; + continental phases in, 18 + + Olorgesailie, 40, 51 + + Ostrich, in China, 54 + + Ovens, 128 + + Oxygen isotopes, 18 + + + Paintings in caves, 83 + + Paleoanthropic man, 50 + + Palestine, burials, 56; + cave sites, 52; + types of man, 69 + + Parpallo, 89 + + Patjitanian, 45, 47 + + Pebble tools, 42 + + Peking cave, 54; + animals in, 54 + + Peking man, 27, 28, 29, 54, 58 + + Pendants, 80; + bone, 114 + + Pestle, 114 + + Peterborough, 141; + assemblage, 141 + + Pictographic signs, 158 + + Pig, wild, 108 + + “Piltdown man,” 29 + + Pins, 80 + + Pithecanthropus, 26, 27, 30, 36 + + Pleistocene, 18, 25 + + Plows developed, 123 + + Points, arrow, 76; + laurel leaf, 78; + shouldered, 78, 79; + split-based bone, 80, 82; + tanged, 76; + willow leaf, 78 + + Potatoes, in America, 145 + + Pottery, 122, 130, 156; + decorated, 142; + painted, 131, 151, 152; + Susa style, 156; + in tombs, 141 + + Prehistory, defined, 7; + range of, 18 + + Pre-neanderthaloids, 30, 31, 37 + + Pre-Solutrean point, 89 + + Pre-Stellenbosch, 48 + + Proto-Literate assemblage, 157-160 + + + Race, 35; + biological, 36; + “pure,” 16 + + Radioactivity, 9, 10 + + Radioactive carbon dates, 18, 92, 120, 130, 135, 156 + + Redfield, Robert, 38, 49 + + Reed, C. A., 128 + + Reindeer, 94 + + Rhinoceros, 93; + in cave art, 85 + + Rhodesian man, 32 + + Riss glaciation, 58 + + Rock-shelters, 58; + art in, 85 + + + Saccopastore, 31 + + Sahara Desert, 34, 102 + + Samarra, 152; + pottery, 131, 152 + + Sangoan industry, 67 + + Sauer, Carl, 136 + + Sbaikian point, 89 + + Schliemann, H., 11, 12 + + Scotland, 171 + + Scraper, flake, 79; + end-scraper on blade, 77, 78; + keel-shaped, 79, 80, 81 + + Sculpture in caves, 83 + + Sebilian III, 126 + + Shaheinab, 135 + + Sheep, wild, 108; + at Skara Brae, 142; + in China, 54 + + Shellfish, 142 + + Ship, Ubaidian, 153 + + Sialk, 126, 134; + assemblage, 134 + + Siberia, 88; + pathway to New World, 98 + + Sickle, 112, 153; + blade, 113, 130 + + Silo, 122 + + Sinanthropus, 27, 30, 35 + + Skara Brae, 142 + + Snails used as food, 128 + + Soan, 47 + + Solecki, R., 116 + + Solo (fossil type), 29, 32 + + Solutrean industry, 77 + + Spear, shaft, 78; + thrower, 82, 83 + + Speech, development of organs of, 25 + + Squash, in America, 145 + + Steinheim fossil skull, 28 + + Stillbay industry, 67 + + Stonehenge, 166 + + Stratification, in caves, 12, 57; + in sites, 12 + + Swanscombe (fossil type), 11, 28 + + Syria, 107 + + + Tabun, 60, 71 + + Tardenoisian, 97 + + Taro, 107 + + Tasa, 135 + + Tayacian, 47, 59 + + Teeth, pierced, in beads and pendants, 114 + + Temples, 123, 155 + + Tepe Gawra, 156 + + Ternafine, 29 + + Teshik Tash, 69 + + Textiles, 122 + + Thong-stropper, 80 + + Tigris River, floods in, 148 + + Toggle, 80 + + Tomatoes, in America, 145 + + Tombs, megalithic, 141 + + Tool-making, 42, 49 + + Tool-preparation traditions, 65 + + Tools, 62; + antler, 80; + blade, 70, 71, 75; + bone, 66; + chopper, 47; + core-biface, 43, 48, 60, 61; + flake, 44, 47, 51, 60, 64; + flint, 80, 127; + ground stone, 68, 127; + handles, 94; + pebble, 42, 43, 48, 53; + use of, 24 + + Touf (mud wall), 128 + + Toynbee, A. J., 101 + + Trade, 130, 155, 162 + + Traders, 167 + + Traditions, 15; + blade tool, 70; + definition of, 51; + interpretation of, 49; + tool-making, 42, 48; + chopper-tool, 47; + chopper-chopping tool, 45; + core-biface, 43, 48; + flake, 44, 47; + pebble tool, 42, 48 + + Tool-making, prehistory of, 42 + + Turkey, 107, 108 + + + Ubaid, 153; + assemblage, 153-155 + + Urnfields, 168, 169 + + + Village-farming community era, 105, 119 + + + Wad B, 72 + + Wadjak, 34 + + Warka phase, 156; + assemblage, 156 + + Washburn, Sherwood L., 36 + + Water buffalo, domestication of, 107 + + Weidenreich, F., 29, 34 + + Wessex, 166, 167 + + Wheat, wild, 108; + partially domesticated, 127 + + Willow leaf point, 78 + + Windmill Hill, 138; + assemblage, 138, 140 + + Witch doctors, 68 + + Wool, 112; + in garments, 167 + + Writing, 158; + cuneiform, 158 + + Würm I glaciation, 58 + + + Zebu cattle, domestication of, 107 + + Zeuner, F. E., 73 + + + + + * * * * * * + + + + +Transcriber’s note: + +Punctuation, hyphenation, and spelling were made consistent when a +predominant preference was found in this book; otherwise they were not +changed. + +Simple typographical errors were corrected; occasional unbalanced +quotation marks retained. + +Ambiguous hyphens at the ends of lines were retained. + +Index not checked for proper alphabetization or correct page references. + +In the original book, chapter headings were accompanied by +illustrations, sometimes above, sometimes below, and sometimes +adjacent. In this eBook those ilustrations always appear below the +headings. + + + +***END OF THE PROJECT GUTENBERG EBOOK PREHISTORIC MEN*** + + +******* This file should be named 52664-0.txt or 52664-0.zip ******* + + +This and all associated files of various formats will be found in: +http://www.gutenberg.org/dirs/5/2/6/6/52664 + + +Updated editions will replace the previous one--the old editions will +be renamed. + +Creating the works from print editions not protected by U.S. copyright +law means that no one owns a United States copyright in these works, +so the Foundation (and you!) can copy and distribute it in the United +States without permission and without paying copyright +royalties. Special rules, set forth in the General Terms of Use part +of this license, apply to copying and distributing Project +Gutenberg-tm electronic works to protect the PROJECT GUTENBERG-tm +concept and trademark. Project Gutenberg is a registered trademark, +and may not be used if you charge for the eBooks, unless you receive +specific permission. If you do not charge anything for copies of this +eBook, complying with the rules is very easy. You may use this eBook +for nearly any purpose such as creation of derivative works, reports, +performances and research. They may be modified and printed and given +away--you may do practically ANYTHING in the United States with eBooks +not protected by U.S. copyright law. Redistribution is subject to the +trademark license, especially commercial redistribution. + +START: FULL LICENSE + +THE FULL PROJECT GUTENBERG LICENSE +PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK + +To protect the Project Gutenberg-tm mission of promoting the free +distribution of electronic works, by using or distributing this work +(or any other work associated in any way with the phrase "Project +Gutenberg"), you agree to comply with all the terms of the Full +Project Gutenberg-tm License available with this file or online at +www.gutenberg.org/license. + +Section 1. General Terms of Use and Redistributing Project +Gutenberg-tm electronic works + +1.A. By reading or using any part of this Project Gutenberg-tm +electronic work, you indicate that you have read, understand, agree to +and accept all the terms of this license and intellectual property +(trademark/copyright) agreement. If you do not agree to abide by all +the terms of this agreement, you must cease using and return or +destroy all copies of Project Gutenberg-tm electronic works in your +possession. If you paid a fee for obtaining a copy of or access to a +Project Gutenberg-tm electronic work and you do not agree to be bound +by the terms of this agreement, you may obtain a refund from the +person or entity to whom you paid the fee as set forth in paragraph +1.E.8. + +1.B. "Project Gutenberg" is a registered trademark. It may only be +used on or associated in any way with an electronic work by people who +agree to be bound by the terms of this agreement. There are a few +things that you can do with most Project Gutenberg-tm electronic works +even without complying with the full terms of this agreement. See +paragraph 1.C below. There are a lot of things you can do with Project +Gutenberg-tm electronic works if you follow the terms of this +agreement and help preserve free future access to Project Gutenberg-tm +electronic works. See paragraph 1.E below. + +1.C. The Project Gutenberg Literary Archive Foundation ("the +Foundation" or PGLAF), owns a compilation copyright in the collection +of Project Gutenberg-tm electronic works. Nearly all the individual +works in the collection are in the public domain in the United +States. If an individual work is unprotected by copyright law in the +United States and you are located in the United States, we do not +claim a right to prevent you from copying, distributing, performing, +displaying or creating derivative works based on the work as long as +all references to Project Gutenberg are removed. Of course, we hope +that you will support the Project Gutenberg-tm mission of promoting +free access to electronic works by freely sharing Project Gutenberg-tm +works in compliance with the terms of this agreement for keeping the +Project Gutenberg-tm name associated with the work. You can easily +comply with the terms of this agreement by keeping this work in the +same format with its attached full Project Gutenberg-tm License when +you share it without charge with others. + +1.D. The copyright laws of the place where you are located also govern +what you can do with this work. Copyright laws in most countries are +in a constant state of change. If you are outside the United States, +check the laws of your country in addition to the terms of this +agreement before downloading, copying, displaying, performing, +distributing or creating derivative works based on this work or any +other Project Gutenberg-tm work. The Foundation makes no +representations concerning the copyright status of any work in any +country outside the United States. + +1.E. Unless you have removed all references to Project Gutenberg: + +1.E.1. The following sentence, with active links to, or other +immediate access to, the full Project Gutenberg-tm License must appear +prominently whenever any copy of a Project Gutenberg-tm work (any work +on which the phrase "Project Gutenberg" appears, or with which the +phrase "Project Gutenberg" is associated) is accessed, displayed, +performed, viewed, copied or distributed: + + This eBook is for the use of anyone anywhere in the United States and + most other parts of the world at no cost and with almost no + restrictions whatsoever. You may copy it, give it away or re-use it + under the terms of the Project Gutenberg License included with this + eBook or online at www.gutenberg.org. If you are not located in the + United States, you'll have to check the laws of the country where you + are located before using this ebook. + +1.E.2. If an individual Project Gutenberg-tm electronic work is +derived from texts not protected by U.S. copyright law (does not +contain a notice indicating that it is posted with permission of the +copyright holder), the work can be copied and distributed to anyone in +the United States without paying any fees or charges. If you are +redistributing or providing access to a work with the phrase "Project +Gutenberg" associated with or appearing on the work, you must comply +either with the requirements of paragraphs 1.E.1 through 1.E.7 or +obtain permission for the use of the work and the Project Gutenberg-tm +trademark as set forth in paragraphs 1.E.8 or 1.E.9. + +1.E.3. If an individual Project Gutenberg-tm electronic work is posted +with the permission of the copyright holder, your use and distribution +must comply with both paragraphs 1.E.1 through 1.E.7 and any +additional terms imposed by the copyright holder. Additional terms +will be linked to the Project Gutenberg-tm License for all works +posted with the permission of the copyright holder found at the +beginning of this work. + +1.E.4. Do not unlink or detach or remove the full Project Gutenberg-tm +License terms from this work, or any files containing a part of this +work or any other work associated with Project Gutenberg-tm. + +1.E.5. Do not copy, display, perform, distribute or redistribute this +electronic work, or any part of this electronic work, without +prominently displaying the sentence set forth in paragraph 1.E.1 with +active links or immediate access to the full terms of the Project +Gutenberg-tm License. + +1.E.6. You may convert to and distribute this work in any binary, +compressed, marked up, nonproprietary or proprietary form, including +any word processing or hypertext form. However, if you provide access +to or distribute copies of a Project Gutenberg-tm work in a format +other than "Plain Vanilla ASCII" or other format used in the official +version posted on the official Project Gutenberg-tm web site +(www.gutenberg.org), you must, at no additional cost, fee or expense +to the user, provide a copy, a means of exporting a copy, or a means +of obtaining a copy upon request, of the work in its original "Plain +Vanilla ASCII" or other form. Any alternate format must include the +full Project Gutenberg-tm License as specified in paragraph 1.E.1. + +1.E.7. Do not charge a fee for access to, viewing, displaying, +performing, copying or distributing any Project Gutenberg-tm works +unless you comply with paragraph 1.E.8 or 1.E.9. + +1.E.8. You may charge a reasonable fee for copies of or providing +access to or distributing Project Gutenberg-tm electronic works +provided that + +* You pay a royalty fee of 20% of the gross profits you derive from + the use of Project Gutenberg-tm works calculated using the method + you already use to calculate your applicable taxes. The fee is owed + to the owner of the Project Gutenberg-tm trademark, but he has + agreed to donate royalties under this paragraph to the Project + Gutenberg Literary Archive Foundation. Royalty payments must be paid + within 60 days following each date on which you prepare (or are + legally required to prepare) your periodic tax returns. Royalty + payments should be clearly marked as such and sent to the Project + Gutenberg Literary Archive Foundation at the address specified in + Section 4, "Information about donations to the Project Gutenberg + Literary Archive Foundation." + +* You provide a full refund of any money paid by a user who notifies + you in writing (or by e-mail) within 30 days of receipt that s/he + does not agree to the terms of the full Project Gutenberg-tm + License. You must require such a user to return or destroy all + copies of the works possessed in a physical medium and discontinue + all use of and all access to other copies of Project Gutenberg-tm + works. + +* You provide, in accordance with paragraph 1.F.3, a full refund of + any money paid for a work or a replacement copy, if a defect in the + electronic work is discovered and reported to you within 90 days of + receipt of the work. + +* You comply with all other terms of this agreement for free + distribution of Project Gutenberg-tm works. + +1.E.9. If you wish to charge a fee or distribute a Project +Gutenberg-tm electronic work or group of works on different terms than +are set forth in this agreement, you must obtain permission in writing +from both the Project Gutenberg Literary Archive Foundation and The +Project Gutenberg Trademark LLC, the owner of the Project Gutenberg-tm +trademark. Contact the Foundation as set forth in Section 3 below. + +1.F. + +1.F.1. Project Gutenberg volunteers and employees expend considerable +effort to identify, do copyright research on, transcribe and proofread +works not protected by U.S. copyright law in creating the Project +Gutenberg-tm collection. Despite these efforts, Project Gutenberg-tm +electronic works, and the medium on which they may be stored, may +contain "Defects," such as, but not limited to, incomplete, inaccurate +or corrupt data, transcription errors, a copyright or other +intellectual property infringement, a defective or damaged disk or +other medium, a computer virus, or computer codes that damage or +cannot be read by your equipment. + +1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for the "Right +of Replacement or Refund" described in paragraph 1.F.3, the Project +Gutenberg Literary Archive Foundation, the owner of the Project +Gutenberg-tm trademark, and any other party distributing a Project +Gutenberg-tm electronic work under this agreement, disclaim all +liability to you for damages, costs and expenses, including legal +fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT +LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT EXCEPT THOSE +PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE THAT THE FOUNDATION, THE +TRADEMARK OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE +LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE OR +INCIDENTAL DAMAGES EVEN IF YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH +DAMAGE. + +1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you discover a +defect in this electronic work within 90 days of receiving it, you can +receive a refund of the money (if any) you paid for it by sending a +written explanation to the person you received the work from. If you +received the work on a physical medium, you must return the medium +with your written explanation. The person or entity that provided you +with the defective work may elect to provide a replacement copy in +lieu of a refund. If you received the work electronically, the person +or entity providing it to you may choose to give you a second +opportunity to receive the work electronically in lieu of a refund. If +the second copy is also defective, you may demand a refund in writing +without further opportunities to fix the problem. + +1.F.4. Except for the limited right of replacement or refund set forth +in paragraph 1.F.3, this work is provided to you 'AS-IS', WITH NO +OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PURPOSE. + +1.F.5. Some states do not allow disclaimers of certain implied +warranties or the exclusion or limitation of certain types of +damages. If any disclaimer or limitation set forth in this agreement +violates the law of the state applicable to this agreement, the +agreement shall be interpreted to make the maximum disclaimer or +limitation permitted by the applicable state law. The invalidity or +unenforceability of any provision of this agreement shall not void the +remaining provisions. + +1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation, the +trademark owner, any agent or employee of the Foundation, anyone +providing copies of Project Gutenberg-tm electronic works in +accordance with this agreement, and any volunteers associated with the +production, promotion and distribution of Project Gutenberg-tm +electronic works, harmless from all liability, costs and expenses, +including legal fees, that arise directly or indirectly from any of +the following which you do or cause to occur: (a) distribution of this +or any Project Gutenberg-tm work, (b) alteration, modification, or +additions or deletions to any Project Gutenberg-tm work, and (c) any +Defect you cause. + +Section 2. Information about the Mission of Project Gutenberg-tm + +Project Gutenberg-tm is synonymous with the free distribution of +electronic works in formats readable by the widest variety of +computers including obsolete, old, middle-aged and new computers. It +exists because of the efforts of hundreds of volunteers and donations +from people in all walks of life. + +Volunteers and financial support to provide volunteers with the +assistance they need are critical to reaching Project Gutenberg-tm's +goals and ensuring that the Project Gutenberg-tm collection will +remain freely available for generations to come. In 2001, the Project +Gutenberg Literary Archive Foundation was created to provide a secure +and permanent future for Project Gutenberg-tm and future +generations. To learn more about the Project Gutenberg Literary +Archive Foundation and how your efforts and donations can help, see +Sections 3 and 4 and the Foundation information page at +www.gutenberg.org + +Section 3. Information about the Project Gutenberg Literary +Archive Foundation + +The Project Gutenberg Literary Archive Foundation is a non profit +501(c)(3) educational corporation organized under the laws of the +state of Mississippi and granted tax exempt status by the Internal +Revenue Service. The Foundation's EIN or federal tax identification +number is 64-6221541. Contributions to the Project Gutenberg Literary +Archive Foundation are tax deductible to the full extent permitted by +U.S. federal laws and your state's laws. + +The Foundation's principal office is in Fairbanks, Alaska, with the +mailing address: PO Box 750175, Fairbanks, AK 99775, but its +volunteers and employees are scattered throughout numerous +locations. Its business office is located at 809 North 1500 West, Salt +Lake City, UT 84116, (801) 596-1887. Email contact links and up to +date contact information can be found at the Foundation's web site and +official page at www.gutenberg.org/contact + +For additional contact information: + + Dr. Gregory B. Newby + Chief Executive and Director + gbnewby@pglaf.org + +Section 4. Information about Donations to the Project Gutenberg +Literary Archive Foundation + +Project Gutenberg-tm depends upon and cannot survive without wide +spread public support and donations to carry out its mission of +increasing the number of public domain and licensed works that can be +freely distributed in machine readable form accessible by the widest +array of equipment including outdated equipment. Many small donations +($1 to $5,000) are particularly important to maintaining tax exempt +status with the IRS. + +The Foundation is committed to complying with the laws regulating +charities and charitable donations in all 50 states of the United +States. Compliance requirements are not uniform and it takes a +considerable effort, much paperwork and many fees to meet and keep up +with these requirements. We do not solicit donations in locations +where we have not received written confirmation of compliance. To SEND +DONATIONS or determine the status of compliance for any particular +state visit www.gutenberg.org/donate + +While we cannot and do not solicit contributions from states where we +have not met the solicitation requirements, we know of no prohibition +against accepting unsolicited donations from donors in such states who +approach us with offers to donate. + +International donations are gratefully accepted, but we cannot make +any statements concerning tax treatment of donations received from +outside the United States. U.S. laws alone swamp our small staff. + +Please check the Project Gutenberg Web pages for current donation +methods and addresses. Donations are accepted in a number of other +ways including checks, online payments and credit card donations. To +donate, please visit: www.gutenberg.org/donate + +Section 5. General Information About Project Gutenberg-tm electronic works. + +Professor Michael S. Hart was the originator of the Project +Gutenberg-tm concept of a library of electronic works that could be +freely shared with anyone. For forty years, he produced and +distributed Project Gutenberg-tm eBooks with only a loose network of +volunteer support. + +Project Gutenberg-tm eBooks are often created from several printed +editions, all of which are confirmed as not protected by copyright in +the U.S. unless a copyright notice is included. Thus, we do not +necessarily keep eBooks in compliance with any particular paper +edition. + +Most people start at our Web site which has the main PG search +facility: www.gutenberg.org + +This Web site includes information about Project Gutenberg-tm, +including how to make donations to the Project Gutenberg Literary +Archive Foundation, how to help produce our new eBooks, and how to +subscribe to our email newsletter to hear about new eBooks. diff --git a/ciphers/transposition_cipher_encrypt_decrypt_file.py b/ciphers/transposition_cipher_encrypt_decrypt_file.py new file mode 100644 index 000000000..5c3eaaca6 --- /dev/null +++ b/ciphers/transposition_cipher_encrypt_decrypt_file.py @@ -0,0 +1,36 @@ +from __future__ import print_function +import time, os, sys +import transposition_cipher as transCipher + +def main(): + inputFile = 'Prehistoric Men.txt' + outputFile = 'Output.txt' + key = int(raw_input('Enter key: ')) + mode = raw_input('Encrypt/Decrypt [e/d]: ') + + if not os.path.exists(inputFile): + print('File %s does not exist. Quitting...' % inputFile) + sys.exit() + if os.path.exists(outputFile): + print('Overwrite %s? [y/n]' % outputFile) + response = raw_input('> ') + if not response.lower().startswith('y'): + sys.exit() + + startTime = time.time() + if mode.lower().startswith('e'): + content = open(inputFile).read() + translated = transCipher.encryptMessage(key, content) + elif mode.lower().startswith('d'): + content = open(outputFile).read() + translated =transCipher .decryptMessage(key, content) + + outputObj = open(outputFile, 'w') + outputObj.write(translated) + outputObj.close() + + totalTime = round(time.time() - startTime, 2) + print(('Done (', totalTime, 'seconds )')) + +if __name__ == '__main__': + main() diff --git a/ciphers/xor_cipher.py b/ciphers/xor_cipher.py new file mode 100644 index 000000000..727fac3b0 --- /dev/null +++ b/ciphers/xor_cipher.py @@ -0,0 +1,209 @@ +""" + author: Christian Bender + date: 21.12.2017 + class: XORCipher + + This class implements the XOR-cipher algorithm and provides + some useful methods for encrypting and decrypting strings and + files. + + Overview about methods + + - encrypt : list of char + - decrypt : list of char + - encrypt_string : str + - decrypt_string : str + - encrypt_file : boolean + - decrypt_file : boolean +""" +class XORCipher(object): + + def __init__(self, key = 0): + """ + simple constructor that receives a key or uses + default key = 0 + """ + + #private field + self.__key = key + + def encrypt(self, content, key): + """ + input: 'content' of type string and 'key' of type int + output: encrypted string 'content' as a list of chars + if key not passed the method uses the key by the constructor. + otherwise key = 1 + """ + + # precondition + assert (isinstance(key,int) and isinstance(content,str)) + + key = key or self.__key or 1 + + # make sure key can be any size + while (key > 255): + key -= 255 + + # This will be returned + ans = [] + + for ch in content: + ans.append(chr(ord(ch) ^ key)) + + return ans + + def decrypt(self,content,key): + """ + input: 'content' of type list and 'key' of type int + output: decrypted string 'content' as a list of chars + if key not passed the method uses the key by the constructor. + otherwise key = 1 + """ + + # precondition + assert (isinstance(key,int) and isinstance(content,list)) + + key = key or self.__key or 1 + + # make sure key can be any size + while (key > 255): + key -= 255 + + # This will be returned + ans = [] + + for ch in content: + ans.append(chr(ord(ch) ^ key)) + + return ans + + + def encrypt_string(self,content, key = 0): + """ + input: 'content' of type string and 'key' of type int + output: encrypted string 'content' + if key not passed the method uses the key by the constructor. + otherwise key = 1 + """ + + # precondition + assert (isinstance(key,int) and isinstance(content,str)) + + key = key or self.__key or 1 + + # make sure key can be any size + while (key > 255): + key -= 255 + + # This will be returned + ans = "" + + for ch in content: + ans += chr(ord(ch) ^ key) + + return ans + + def decrypt_string(self,content,key = 0): + """ + input: 'content' of type string and 'key' of type int + output: decrypted string 'content' + if key not passed the method uses the key by the constructor. + otherwise key = 1 + """ + + # precondition + assert (isinstance(key,int) and isinstance(content,str)) + + key = key or self.__key or 1 + + # make sure key can be any size + while (key > 255): + key -= 255 + + # This will be returned + ans = "" + + for ch in content: + ans += chr(ord(ch) ^ key) + + return ans + + + def encrypt_file(self, file, key = 0): + """ + input: filename (str) and a key (int) + output: returns true if encrypt process was + successful otherwise false + if key not passed the method uses the key by the constructor. + otherwise key = 1 + """ + + #precondition + assert (isinstance(file,str) and isinstance(key,int)) + + try: + with open(file,"r") as fin: + with open("encrypt.out","w+") as fout: + + # actual encrypt-process + for line in fin: + fout.write(self.encrypt_string(line,key)) + + except: + return False + + return True + + + def decrypt_file(self,file, key): + """ + input: filename (str) and a key (int) + output: returns true if decrypt process was + successful otherwise false + if key not passed the method uses the key by the constructor. + otherwise key = 1 + """ + + #precondition + assert (isinstance(file,str) and isinstance(key,int)) + + try: + with open(file,"r") as fin: + with open("decrypt.out","w+") as fout: + + # actual encrypt-process + for line in fin: + fout.write(self.decrypt_string(line,key)) + + except: + return False + + return True + + + + +# Tests +# crypt = XORCipher() +# key = 67 + +# # test enrcypt +# print crypt.encrypt("hallo welt",key) +# # test decrypt +# print crypt.decrypt(crypt.encrypt("hallo welt",key), key) + +# # test encrypt_string +# print crypt.encrypt_string("hallo welt",key) + +# # test decrypt_string +# print crypt.decrypt_string(crypt.encrypt_string("hallo welt",key),key) + +# if (crypt.encrypt_file("test.txt",key)): +# print "encrypt successful" +# else: +# print "encrypt unsuccessful" + +# if (crypt.decrypt_file("encrypt.out",key)): +# print "decrypt successful" +# else: +# print "decrypt unsuccessful" \ No newline at end of file diff --git a/data_structures/arrays.py b/data_structures/arrays.py new file mode 100644 index 000000000..3ec9f8976 --- /dev/null +++ b/data_structures/arrays.py @@ -0,0 +1,3 @@ +arr = [10, 20, 30, 40] +arr[1] = 30 +print(arr) diff --git a/data_structures/avl.py b/data_structures/avl.py new file mode 100644 index 000000000..d01e8f825 --- /dev/null +++ b/data_structures/avl.py @@ -0,0 +1,181 @@ +""" +An AVL tree +""" +from __future__ import print_function + + +class Node: + + def __init__(self, label): + self.label = label + self._parent = None + self._left = None + self._right = None + self.height = 0 + + @property + def right(self): + return self._right + + @right.setter + def right(self, node): + if node is not None: + node._parent = self + self._right = node + + @property + def left(self): + return self._left + + @left.setter + def left(self, node): + if node is not None: + node._parent = self + self._left = node + + @property + def parent(self): + return self._parent + + @parent.setter + def parent(self, node): + if node is not None: + self._parent = node + self.height = self.parent.height + 1 + else: + self.height = 0 + + +class AVL: + + def __init__(self): + self.root = None + self.size = 0 + + def insert(self, value): + node = Node(value) + + if self.root is None: + self.root = node + self.root.height = 0 + self.size = 1 + else: + # Same as Binary Tree + dad_node = None + curr_node = self.root + + while True: + if curr_node is not None: + + dad_node = curr_node + + if node.label < curr_node.label: + curr_node = curr_node.left + else: + curr_node = curr_node.right + else: + node.height = dad_node.height + dad_node.height += 1 + if node.label < dad_node.label: + dad_node.left = node + else: + dad_node.right = node + self.rebalance(node) + self.size += 1 + break + + def rebalance(self, node): + n = node + + while n is not None: + height_right = n.height + height_left = n.height + + if n.right is not None: + height_right = n.right.height + + if n.left is not None: + height_left = n.left.height + + if abs(height_left - height_right) > 1: + if height_left > height_right: + left_child = n.left + if left_child is not None: + h_right = (left_child.right.height + if (left_child.right is not None) else 0) + h_left = (left_child.left.height + if (left_child.left is not None) else 0) + if (h_left > h_right): + self.rotate_left(n) + break + else: + self.double_rotate_right(n) + break + else: + right_child = n.right + if right_child is not None: + h_right = (right_child.right.height + if (right_child.right is not None) else 0) + h_left = (right_child.left.height + if (right_child.left is not None) else 0) + if (h_left > h_right): + self.double_rotate_left(n) + break + else: + self.rotate_right(n) + break + n = n.parent + + def rotate_left(self, node): + aux = node.parent.label + node.parent.label = node.label + node.parent.right = Node(aux) + node.parent.right.height = node.parent.height + 1 + node.parent.left = node.right + + + def rotate_right(self, node): + aux = node.parent.label + node.parent.label = node.label + node.parent.left = Node(aux) + node.parent.left.height = node.parent.height + 1 + node.parent.right = node.right + + def double_rotate_left(self, node): + self.rotate_right(node.getRight().getRight()) + self.rotate_left(node) + + def double_rotate_right(self, node): + self.rotate_left(node.getLeft().getLeft()) + self.rotate_right(node) + + def empty(self): + if self.root is None: + return True + return False + + def preShow(self, curr_node): + if curr_node is not None: + self.preShow(curr_node.left) + print(curr_node.label, end=" ") + self.preShow(curr_node.right) + + def preorder(self, curr_node): + if curr_node is not None: + self.preShow(curr_node.left) + self.preShow(curr_node.right) + print(curr_node.label, end=" ") + + def getRoot(self): + return self.root + +t = AVL() +t.insert(1) +t.insert(2) +t.insert(3) +# t.preShow(t.root) +# print("\n") +# t.insert(4) +# t.insert(5) +# t.preShow(t.root) +# t.preorden(t.root) diff --git a/data_structures/binary tree/FenwickTree.py b/data_structures/binary tree/FenwickTree.py new file mode 100644 index 000000000..f429161c8 --- /dev/null +++ b/data_structures/binary tree/FenwickTree.py @@ -0,0 +1,29 @@ +from __future__ import print_function +class FenwickTree: + + def __init__(self, SIZE): # create fenwick tree with size SIZE + self.Size = SIZE + self.ft = [0 for i in range (0,SIZE)] + + def update(self, i, val): # update data (adding) in index i in O(lg N) + while (i < self.Size): + self.ft[i] += val + i += i & (-i) + + def query(self, i): # query cumulative data from index 0 to i in O(lg N) + ret = 0 + while (i > 0): + ret += self.ft[i] + i -= i & (-i) + return ret + +if __name__ == '__main__': + f = FenwickTree(100) + f.update(1,20) + f.update(4,4) + print (f.query(1)) + print (f.query(3)) + print (f.query(4)) + f.update(2,-5) + print (f.query(1)) + print (f.query(3)) diff --git a/data_structures/binary tree/LazySegmentTree.py b/data_structures/binary tree/LazySegmentTree.py new file mode 100644 index 000000000..9b14b24e8 --- /dev/null +++ b/data_structures/binary tree/LazySegmentTree.py @@ -0,0 +1,91 @@ +from __future__ import print_function +import math + +class SegmentTree: + + def __init__(self, N): + self.N = N + self.st = [0 for i in range(0,4*N)] # approximate the overall size of segment tree with array N + self.lazy = [0 for i in range(0,4*N)] # create array to store lazy update + self.flag = [0 for i in range(0,4*N)] # flag for lazy update + + def left(self, idx): + return idx*2 + + def right(self, idx): + return idx*2 + 1 + + def build(self, idx, l, r, A): + if l==r: + self.st[idx] = A[l-1] + else : + mid = (l+r)//2 + self.build(self.left(idx),l,mid, A) + self.build(self.right(idx),mid+1,r, A) + self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)]) + + # update with O(lg N) (Normal segment tree without lazy update will take O(Nlg N) for each update) + def update(self, idx, l, r, a, b, val): # update(1, 1, N, a, b, v) for update val v to [a,b] + if self.flag[idx] == True: + self.st[idx] = self.lazy[idx] + self.flag[idx] = False + if l!=r: + self.lazy[self.left(idx)] = self.lazy[idx] + self.lazy[self.right(idx)] = self.lazy[idx] + self.flag[self.left(idx)] = True + self.flag[self.right(idx)] = True + + if r < a or l > b: + return True + if l >= a and r <= b : + self.st[idx] = val + if l!=r: + self.lazy[self.left(idx)] = val + self.lazy[self.right(idx)] = val + self.flag[self.left(idx)] = True + self.flag[self.right(idx)] = True + return True + mid = (l+r)//2 + self.update(self.left(idx),l,mid,a,b,val) + self.update(self.right(idx),mid+1,r,a,b,val) + self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)]) + return True + + # query with O(lg N) + def query(self, idx, l, r, a, b): #query(1, 1, N, a, b) for query max of [a,b] + if self.flag[idx] == True: + self.st[idx] = self.lazy[idx] + self.flag[idx] = False + if l != r: + self.lazy[self.left(idx)] = self.lazy[idx] + self.lazy[self.right(idx)] = self.lazy[idx] + self.flag[self.left(idx)] = True + self.flag[self.right(idx)] = True + if r < a or l > b: + return -math.inf + if l >= a and r <= b: + return self.st[idx] + mid = (l+r)//2 + q1 = self.query(self.left(idx),l,mid,a,b) + q2 = self.query(self.right(idx),mid+1,r,a,b) + return max(q1,q2) + + def showData(self): + showList = [] + for i in range(1,N+1): + showList += [self.query(1, 1, self.N, i, i)] + print (showList) + + +if __name__ == '__main__': + A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8] + N = 15 + segt = SegmentTree(N) + segt.build(1,1,N,A) + print (segt.query(1,1,N,4,6)) + print (segt.query(1,1,N,7,11)) + print (segt.query(1,1,N,7,12)) + segt.update(1,1,N,1,3,111) + print (segt.query(1,1,N,1,15)) + segt.update(1,1,N,7,8,235) + segt.showData() diff --git a/data_structures/binary tree/SegmentTree.py b/data_structures/binary tree/SegmentTree.py new file mode 100644 index 000000000..001bf999f --- /dev/null +++ b/data_structures/binary tree/SegmentTree.py @@ -0,0 +1,71 @@ +from __future__ import print_function +import math + +class SegmentTree: + + def __init__(self, A): + self.N = len(A) + self.st = [0] * (4 * self.N) # approximate the overall size of segment tree with array N + self.build(1, 0, self.N - 1) + + def left(self, idx): + return idx * 2 + + def right(self, idx): + return idx * 2 + 1 + + def build(self, idx, l, r): + if l == r: + self.st[idx] = A[l] + else: + mid = (l + r) // 2 + self.build(self.left(idx), l, mid) + self.build(self.right(idx), mid + 1, r) + self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)]) + + def update(self, a, b, val): + return self.update_recursive(1, 0, self.N - 1, a - 1, b - 1, val) + + def update_recursive(self, idx, l, r, a, b, val): # update(1, 1, N, a, b, v) for update val v to [a,b] + if r < a or l > b: + return True + if l == r : + self.st[idx] = val + return True + mid = (l+r)//2 + self.update_recursive(self.left(idx), l, mid, a, b, val) + self.update_recursive(self.right(idx), mid+1, r, a, b, val) + self.st[idx] = max(self.st[self.left(idx)] , self.st[self.right(idx)]) + return True + + def query(self, a, b): + return self.query_recursive(1, 0, self.N - 1, a - 1, b - 1) + + def query_recursive(self, idx, l, r, a, b): #query(1, 1, N, a, b) for query max of [a,b] + if r < a or l > b: + return -math.inf + if l >= a and r <= b: + return self.st[idx] + mid = (l+r)//2 + q1 = self.query_recursive(self.left(idx), l, mid, a, b) + q2 = self.query_recursive(self.right(idx), mid + 1, r, a, b) + return max(q1, q2) + + def showData(self): + showList = [] + for i in range(1,N+1): + showList += [self.query(i, i)] + print (showList) + + +if __name__ == '__main__': + A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8] + N = 15 + segt = SegmentTree(A) + print (segt.query(4, 6)) + print (segt.query(7, 11)) + print (segt.query(7, 12)) + segt.update(1,3,111) + print (segt.query(1, 15)) + segt.update(7,8,235) + segt.showData() diff --git a/data_structures/binary tree/binary_search_tree.py b/data_structures/binary tree/binary_search_tree.py new file mode 100644 index 000000000..b4021e4f8 --- /dev/null +++ b/data_structures/binary tree/binary_search_tree.py @@ -0,0 +1,258 @@ +''' +A binary search Tree +''' +from __future__ import print_function +class Node: + + def __init__(self, label, parent): + self.label = label + self.left = None + self.right = None + #Added in order to delete a node easier + self.parent = parent + + def getLabel(self): + return self.label + + def setLabel(self, label): + self.label = label + + def getLeft(self): + return self.left + + def setLeft(self, left): + self.left = left + + def getRight(self): + return self.right + + def setRight(self, right): + self.right = right + + def getParent(self): + return self.parent + + def setParent(self, parent): + self.parent = parent + +class BinarySearchTree: + + def __init__(self): + self.root = None + + def insert(self, label): + # Create a new Node + new_node = Node(label, None) + # If Tree is empty + if self.empty(): + self.root = new_node + else: + #If Tree is not empty + curr_node = self.root + #While we don't get to a leaf + while curr_node is not None: + #We keep reference of the parent node + parent_node = curr_node + #If node label is less than current node + if new_node.getLabel() < curr_node.getLabel(): + #We go left + curr_node = curr_node.getLeft() + else: + #Else we go right + curr_node = curr_node.getRight() + #We insert the new node in a leaf + if new_node.getLabel() < parent_node.getLabel(): + parent_node.setLeft(new_node) + else: + parent_node.setRight(new_node) + #Set parent to the new node + new_node.setParent(parent_node) + + def delete(self, label): + if (not self.empty()): + #Look for the node with that label + node = self.getNode(label) + #If the node exists + if(node is not None): + #If it has no children + if(node.getLeft() is None and node.getRight() is None): + self.__reassignNodes(node, None) + node = None + #Has only right children + elif(node.getLeft() is None and node.getRight() is not None): + self.__reassignNodes(node, node.getRight()) + #Has only left children + elif(node.getLeft() is not None and node.getRight() is None): + self.__reassignNodes(node, node.getLeft()) + #Has two children + else: + #Gets the max value of the left branch + tmpNode = self.getMax(node.getLeft()) + #Deletes the tmpNode + self.delete(tmpNode.getLabel()) + #Assigns the value to the node to delete and keesp tree structure + node.setLabel(tmpNode.getLabel()) + + def getNode(self, label): + curr_node = None + #If the tree is not empty + if(not self.empty()): + #Get tree root + curr_node = self.getRoot() + #While we don't find the node we look for + #I am using lazy evaluation here to avoid NoneType Attribute error + while curr_node is not None and curr_node.getLabel() is not label: + #If node label is less than current node + if label < curr_node.getLabel(): + #We go left + curr_node = curr_node.getLeft() + else: + #Else we go right + curr_node = curr_node.getRight() + return curr_node + + def getMax(self, root = None): + if(root is not None): + curr_node = root + else: + #We go deep on the right branch + curr_node = self.getRoot() + if(not self.empty()): + while(curr_node.getRight() is not None): + curr_node = curr_node.getRight() + return curr_node + + def getMin(self, root = None): + if(root is not None): + curr_node = root + else: + #We go deep on the left branch + curr_node = self.getRoot() + if(not self.empty()): + curr_node = self.getRoot() + while(curr_node.getLeft() is not None): + curr_node = curr_node.getLeft() + return curr_node + + def empty(self): + if self.root is None: + return True + return False + + def __InOrderTraversal(self, curr_node): + nodeList = [] + if curr_node is not None: + nodeList.insert(0, curr_node) + nodeList = nodeList + self.__InOrderTraversal(curr_node.getLeft()) + nodeList = nodeList + self.__InOrderTraversal(curr_node.getRight()) + return nodeList + + def getRoot(self): + return self.root + + def __isRightChildren(self, node): + if(node == node.getParent().getRight()): + return True + return False + + def __reassignNodes(self, node, newChildren): + if(newChildren is not None): + newChildren.setParent(node.getParent()) + if(node.getParent() is not None): + #If it is the Right Children + if(self.__isRightChildren(node)): + node.getParent().setRight(newChildren) + else: + #Else it is the left children + node.getParent().setLeft(newChildren) + + #This function traversal the tree. By default it returns an + #In order traversal list. You can pass a function to traversal + #The tree as needed by client code + def traversalTree(self, traversalFunction = None, root = None): + if(traversalFunction is None): + #Returns a list of nodes in preOrder by default + return self.__InOrderTraversal(self.root) + else: + #Returns a list of nodes in the order that the users wants to + return traversalFunction(self.root) + + #Returns an string of all the nodes labels in the list + #In Order Traversal + def __str__(self): + list = self.__InOrderTraversal(self.root) + str = "" + for x in list: + str = str + " " + x.getLabel().__str__() + return str + +def InPreOrder(curr_node): + nodeList = [] + if curr_node is not None: + nodeList = nodeList + InPreOrder(curr_node.getLeft()) + nodeList.insert(0, curr_node.getLabel()) + nodeList = nodeList + InPreOrder(curr_node.getRight()) + return nodeList + +def testBinarySearchTree(): + ''' + Example + 8 + / \ + 3 10 + / \ \ + 1 6 14 + / \ / + 4 7 13 + ''' + + ''' + Example After Deletion + 7 + / \ + 1 4 + + ''' + t = BinarySearchTree() + t.insert(8) + t.insert(3) + t.insert(6) + t.insert(1) + t.insert(10) + t.insert(14) + t.insert(13) + t.insert(4) + t.insert(7) + + #Prints all the elements of the list in order traversal + print(t.__str__()) + + if(t.getNode(6) is not None): + print("The label 6 exists") + else: + print("The label 6 doesn't exist") + + if(t.getNode(-1) is not None): + print("The label -1 exists") + else: + print("The label -1 doesn't exist") + + if(not t.empty()): + print(("Max Value: ", t.getMax().getLabel())) + print(("Min Value: ", t.getMin().getLabel())) + + t.delete(13) + t.delete(10) + t.delete(8) + t.delete(3) + t.delete(6) + t.delete(14) + + #Gets all the elements of the tree In pre order + #And it prints them + list = t.traversalTree(InPreOrder, t.root) + for x in list: + print(x) + +if __name__ == "__main__": + testBinarySearchTree() diff --git a/data_structures/graph/bellman_ford.py b/data_structures/graph/bellman_ford.py new file mode 100644 index 000000000..f5e1ac983 --- /dev/null +++ b/data_structures/graph/bellman_ford.py @@ -0,0 +1,54 @@ +from __future__ import print_function + +def printDist(dist, V): + print("\nVertex Distance") + for i in range(V): + if dist[i] != float('inf') : + print(i,"\t",int(dist[i]),end = "\t") + else: + print(i,"\t","INF",end="\t") + print() + +def BellmanFord(graph, V, E, src): + mdist=[float('inf') for i in range(V)] + mdist[src] = 0.0 + + for i in range(V-1): + for j in range(V): + u = graph[j]["src"] + v = graph[j]["dst"] + w = graph[j]["weight"] + + if mdist[u] != float('inf') and mdist[u] + w < mdist[v]: + mdist[v] = mdist[u] + w + for j in range(V): + u = graph[j]["src"] + v = graph[j]["dst"] + w = graph[j]["weight"] + + if mdist[u] != float('inf') and mdist[u] + w < mdist[v]: + print("Negative cycle found. Solution not possible.") + return + + printDist(mdist, V) + + + +#MAIN +V = int(raw_input("Enter number of vertices: ")) +E = int(raw_input("Enter number of edges: ")) + +graph = [dict() for j in range(E)] + +for i in range(V): + graph[i][i] = 0.0 + +for i in range(E): + print("\nEdge ",i+1) + src = int(raw_input("Enter source:")) + dst = int(raw_input("Enter destination:")) + weight = float(raw_input("Enter weight:")) + graph[i] = {"src": src,"dst": dst, "weight": weight} + +gsrc = int(raw_input("\nEnter shortest path source:")) +BellmanFord(graph, V, E, gsrc) diff --git a/data_structures/graph/breadth_first_search.py b/data_structures/graph/breadth_first_search.py new file mode 100644 index 000000000..3992e2d4d --- /dev/null +++ b/data_structures/graph/breadth_first_search.py @@ -0,0 +1,67 @@ +#!/usr/bin/python +# encoding=utf8 + +""" Author: OMKAR PATHAK """ + +from __future__ import print_function + + +class Graph(): + def __init__(self): + self.vertex = {} + + # for printing the Graph vertexes + def printGraph(self): + for i in self.vertex.keys(): + print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]])) + + # for adding the edge beween two vertexes + def addEdge(self, fromVertex, toVertex): + # check if vertex is already present, + if fromVertex in self.vertex.keys(): + self.vertex[fromVertex].append(toVertex) + else: + # else make a new vertex + self.vertex[fromVertex] = [toVertex] + + def BFS(self, startVertex): + # Take a list for stoting already visited vertexes + visited = [False] * len(self.vertex) + + # create a list to store all the vertexes for BFS + queue = [] + + # mark the source node as visited and enqueue it + visited[startVertex] = True + queue.append(startVertex) + + while queue: + startVertex = queue.pop(0) + print(startVertex, end = ' ') + + # mark all adjacent nodes as visited and print them + for i in self.vertex[startVertex]: + if visited[i] == False: + queue.append(i) + visited[i] = True + +if __name__ == '__main__': + g = Graph() + g.addEdge(0, 1) + g.addEdge(0, 2) + g.addEdge(1, 2) + g.addEdge(2, 0) + g.addEdge(2, 3) + g.addEdge(3, 3) + + g.printGraph() + print('BFS:') + g.BFS(2) + + # OUTPUT: + # 0  ->  1 -> 2 + # 1  ->  2 + # 2  ->  0 -> 3 + # 3  ->  3 + # BFS: + # 2 0 3 1 diff --git a/data_structures/graph/depth_first_search.py b/data_structures/graph/depth_first_search.py new file mode 100644 index 000000000..98faf6135 --- /dev/null +++ b/data_structures/graph/depth_first_search.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# encoding=utf8 + +""" Author: OMKAR PATHAK """ +from __future__ import print_function + + +class Graph(): + def __init__(self): + self.vertex = {} + + # for printing the Graph vertexes + def printGraph(self): + print(self.vertex) + for i in self.vertex.keys(): + print(i,' -> ', ' -> '.join([str(j) for j in self.vertex[i]])) + + # for adding the edge beween two vertexes + def addEdge(self, fromVertex, toVertex): + # check if vertex is already present, + if fromVertex in self.vertex.keys(): + self.vertex[fromVertex].append(toVertex) + else: + # else make a new vertex + self.vertex[fromVertex] = [toVertex] + + def DFS(self): + # visited array for storing already visited nodes + visited = [False] * len(self.vertex) + + # call the recursive helper function + for i in range(len(self.vertex)): + if visited[i] == False: + self.DFSRec(i, visited) + + def DFSRec(self, startVertex, visited): + # mark start vertex as visited + visited[startVertex] = True + + print(startVertex, end = ' ') + + # Recur for all the vertexes that are adjacent to this node + for i in self.vertex.keys(): + if visited[i] == False: + self.DFSRec(i, visited) + +if __name__ == '__main__': + g = Graph() + g.addEdge(0, 1) + g.addEdge(0, 2) + g.addEdge(1, 2) + g.addEdge(2, 0) + g.addEdge(2, 3) + g.addEdge(3, 3) + + g.printGraph() + print('DFS:') + g.DFS() + + # OUTPUT: + # 0  ->  1 -> 2 + # 1  ->  2 + # 2  ->  0 -> 3 + # 3  ->  3 + # DFS: + # 0 1 2 3 diff --git a/data_structures/graph/dijkstra.py b/data_structures/graph/dijkstra.py new file mode 100644 index 000000000..2580dd2f0 --- /dev/null +++ b/data_structures/graph/dijkstra.py @@ -0,0 +1,57 @@ +from __future__ import print_function + +def printDist(dist, V): + print("\nVertex Distance") + for i in range(V): + if dist[i] != float('inf') : + print(i,"\t",int(dist[i]),end = "\t") + else: + print(i,"\t","INF",end="\t") + print() + +def minDist(mdist, vset, V): + minVal = float('inf') + minInd = -1 + for i in range(V): + if (not vset[i]) and mdist[i] < minVal : + minInd = i + minVal = mdist[i] + return minInd + +def Dijkstra(graph, V, src): + mdist=[float('inf') for i in range(V)] + vset = [False for i in range(V)] + mdist[src] = 0.0; + + for i in range(V-1): + u = minDist(mdist, vset, V) + vset[u] = True + + for v in range(V): + if (not vset[v]) and graph[u][v]!=float('inf') and mdist[u] + graph[u][v] < mdist[v]: + mdist[v] = mdist[u] + graph[u][v] + + + + printDist(mdist, V) + + + +#MAIN +V = int(raw_input("Enter number of vertices: ")) +E = int(raw_input("Enter number of edges: ")) + +graph = [[float('inf') for i in range(V)] for j in range(V)] + +for i in range(V): + graph[i][i] = 0.0 + +for i in range(E): + print("\nEdge ",i+1) + src = int(raw_input("Enter source:")) + dst = int(raw_input("Enter destination:")) + weight = float(raw_input("Enter weight:")) + graph[src][dst] = weight + +gsrc = int(raw_input("\nEnter shortest path source:")) +Dijkstra(graph, V, gsrc) diff --git a/data_structures/graph/dijkstra_algorithm.py b/data_structures/graph/dijkstra_algorithm.py new file mode 100644 index 000000000..985c7f6c1 --- /dev/null +++ b/data_structures/graph/dijkstra_algorithm.py @@ -0,0 +1,212 @@ +# Title: Dijkstra's Algorithm for finding single source shortest path from scratch +# Author: Shubham Malik +# References: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm + +from __future__ import print_function +import math +import sys +# For storing the vertex set to retreive node with the lowest distance + + +class PriorityQueue: + # Based on Min Heap + def __init__(self): + self.cur_size = 0 + self.array = [] + self.pos = {} # To store the pos of node in array + + def isEmpty(self): + return self.cur_size == 0 + + def min_heapify(self, idx): + lc = self.left(idx) + rc = self.right(idx) + if lc < self.cur_size and self.array(lc)[0] < self.array(idx)[0]: + smallest = lc + else: + smallest = idx + if rc < self.cur_size and self.array(rc)[0] < self.array(smallest)[0]: + smallest = rc + if smallest != idx: + self.swap(idx, smallest) + self.min_heapify(smallest) + + def insert(self, tup): + # Inserts a node into the Priority Queue + self.pos[tup[1]] = self.cur_size + self.cur_size += 1 + self.array.append((sys.maxsize, tup[1])) + self.decrease_key((sys.maxsize, tup[1]), tup[0]) + + def extract_min(self): + # Removes and returns the min element at top of priority queue + min_node = self.array[0][1] + self.array[0] = self.array[self.cur_size - 1] + self.cur_size -= 1 + self.min_heapify(1) + del self.pos[min_node] + return min_node + + def left(self, i): + # returns the index of left child + return 2 * i + 1 + + def right(self, i): + # returns the index of right child + return 2 * i + 2 + + def par(self, i): + # returns the index of parent + return math.floor(i / 2) + + def swap(self, i, j): + # swaps array elements at indices i and j + # update the pos{} + self.pos[self.array[i][1]] = j + self.pos[self.array[j][1]] = i + temp = self.array[i] + self.array[i] = self.array[j] + self.array[j] = temp + + def decrease_key(self, tup, new_d): + idx = self.pos[tup[1]] + # assuming the new_d is atmost old_d + self.array[idx] = (new_d, tup[1]) + while idx > 0 and self.array[self.par(idx)][0] > self.array[idx][0]: + self.swap(idx, self.par(idx)) + idx = self.par(idx) + + +class Graph: + def __init__(self, num): + self.adjList = {} # To store graph: u -> (v,w) + self.num_nodes = num # Number of nodes in graph + # To store the distance from source vertex + self.dist = [0] * self.num_nodes + self.par = [-1] * self.num_nodes # To store the path + + def add_edge(self, u, v, w): + # Edge going from node u to v and v to u with weight w + # u (w)-> v, v (w) -> u + # Check if u already in graph + if u in self.adjList.keys(): + self.adjList[u].append((v, w)) + else: + self.adjList[u] = [(v, w)] + + # Assuming undirected graph + if v in self.adjList.keys(): + self.adjList[v].append((u, w)) + else: + self.adjList[v] = [(u, w)] + + def show_graph(self): + # u -> v(w) + for u in self.adjList: + print(u, '->', ' -> '.join(str("{}({})".format(v, w)) + for v, w in self.adjList[u])) + + def dijkstra(self, src): + # Flush old junk values in par[] + self.par = [-1] * self.num_nodes + # src is the source node + self.dist[src] = 0 + Q = PriorityQueue() + Q.insert((0, src)) # (dist from src, node) + for u in self.adjList.keys(): + if u != src: + self.dist[u] = sys.maxsize # Infinity + self.par[u] = -1 + + while not Q.isEmpty(): + u = Q.extract_min() # Returns node with the min dist from source + # Update the distance of all the neighbours of u and + # if their prev dist was INFINITY then push them in Q + for v, w in self.adjList[u]: + new_dist = self.dist[u] + w + if self.dist[v] > new_dist: + if self.dist[v] == sys.maxsize: + Q.insert((new_dist, v)) + else: + Q.decrease_key((self.dist[v], v), new_dist) + self.dist[v] = new_dist + self.par[v] = u + + # Show the shortest distances from src + self.show_distances(src) + + def show_distances(self, src): + print("Distance from node: {}".format(src)) + for u in range(self.num_nodes): + print('Node {} has distance: {}'.format(u, self.dist[u])) + + def show_path(self, src, dest): + # To show the shortest path from src to dest + # WARNING: Use it *after* calling dijkstra + path = [] + cost = 0 + temp = dest + # Backtracking from dest to src + while self.par[temp] != -1: + path.append(temp) + if temp != src: + for v, w in self.adjList[temp]: + if v == self.par[temp]: + cost += w + break + temp = self.par[temp] + path.append(src) + path.reverse() + + print('----Path to reach {} from {}----'.format(dest, src)) + for u in path: + print('{}'.format(u), end=' ') + if u != dest: + print('-> ', end='') + + print('\nTotal cost of path: ', cost) + + +if __name__ == '__main__': + graph = Graph(9) + graph.add_edge(0, 1, 4) + graph.add_edge(0, 7, 8) + graph.add_edge(1, 2, 8) + graph.add_edge(1, 7, 11) + graph.add_edge(2, 3, 7) + graph.add_edge(2, 8, 2) + graph.add_edge(2, 5, 4) + graph.add_edge(3, 4, 9) + graph.add_edge(3, 5, 14) + graph.add_edge(4, 5, 10) + graph.add_edge(5, 6, 2) + graph.add_edge(6, 7, 1) + graph.add_edge(6, 8, 6) + graph.add_edge(7, 8, 7) + graph.show_graph() + graph.dijkstra(0) + graph.show_path(0, 4) + +# OUTPUT +# 0 -> 1(4) -> 7(8) +# 1 -> 0(4) -> 2(8) -> 7(11) +# 7 -> 0(8) -> 1(11) -> 6(1) -> 8(7) +# 2 -> 1(8) -> 3(7) -> 8(2) -> 5(4) +# 3 -> 2(7) -> 4(9) -> 5(14) +# 8 -> 2(2) -> 6(6) -> 7(7) +# 5 -> 2(4) -> 3(14) -> 4(10) -> 6(2) +# 4 -> 3(9) -> 5(10) +# 6 -> 5(2) -> 7(1) -> 8(6) +# Distance from node: 0 +# Node 0 has distance: 0 +# Node 1 has distance: 4 +# Node 2 has distance: 12 +# Node 3 has distance: 19 +# Node 4 has distance: 21 +# Node 5 has distance: 11 +# Node 6 has distance: 9 +# Node 7 has distance: 8 +# Node 8 has distance: 14 +# ----Path to reach 4 from 0---- +# 0 -> 7 -> 6 -> 5 -> 4 +# Total cost of path: 21 diff --git a/data_structures/graph/even_tree.py b/data_structures/graph/even_tree.py new file mode 100644 index 000000000..9383ea9a1 --- /dev/null +++ b/data_structures/graph/even_tree.py @@ -0,0 +1,70 @@ +""" +You are given a tree(a simple connected graph with no cycles). The tree has N +nodes numbered from 1 to N and is rooted at node 1. + +Find the maximum number of edges you can remove from the tree to get a forest +such that each connected component of the forest contains an even number of +nodes. + +Constraints +2 <= 2 <= 100 + +Note: The tree input will be such that it can always be decomposed into +components containing an even number of nodes. +""" +from __future__ import print_function +# pylint: disable=invalid-name +from collections import defaultdict + + +def dfs(start): + """DFS traversal""" + # pylint: disable=redefined-outer-name + ret = 1 + visited[start] = True + for v in tree.get(start): + if v not in visited: + ret += dfs(v) + if ret % 2 == 0: + cuts.append(start) + return ret + + +def even_tree(): + """ + 2 1 + 3 1 + 4 3 + 5 2 + 6 1 + 7 2 + 8 6 + 9 8 + 10 8 + On removing edges (1,3) and (1,6), we can get the desired result 2. + """ + dfs(1) + + +if __name__ == '__main__': + n, m = 10, 9 + tree = defaultdict(list) + visited = {} + cuts = [] + count = 0 + edges = [ + (2, 1), + (3, 1), + (4, 3), + (5, 2), + (6, 1), + (7, 2), + (8, 6), + (9, 8), + (10, 8), + ] + for u, v in edges: + tree[u].append(v) + tree[v].append(u) + even_tree() + print(len(cuts) - 1) diff --git a/data_structures/graph/floyd_warshall.py b/data_structures/graph/floyd_warshall.py new file mode 100644 index 000000000..64d41c2f8 --- /dev/null +++ b/data_structures/graph/floyd_warshall.py @@ -0,0 +1,48 @@ +from __future__ import print_function + +def printDist(dist, V): + print("\nThe shortest path matrix using Floyd Warshall algorithm\n") + for i in range(V): + for j in range(V): + if dist[i][j] != float('inf') : + print(int(dist[i][j]),end = "\t") + else: + print("INF",end="\t") + print() + + + +def FloydWarshall(graph, V): + dist=[[float('inf') for i in range(V)] for j in range(V)] + + for i in range(V): + for j in range(V): + dist[i][j] = graph[i][j] + + for k in range(V): + for i in range(V): + for j in range(V): + if dist[i][k]!=float('inf') and dist[k][j]!=float('inf') and dist[i][k]+dist[k][j] < dist[i][j]: + dist[i][j] = dist[i][k] + dist[k][j] + + printDist(dist, V) + + + +#MAIN +V = int(raw_input("Enter number of vertices: ")) +E = int(raw_input("Enter number of edges: ")) + +graph = [[float('inf') for i in range(V)] for j in range(V)] + +for i in range(V): + graph[i][i] = 0.0 + +for i in range(E): + print("\nEdge ",i+1) + src = int(raw_input("Enter source:")) + dst = int(raw_input("Enter destination:")) + weight = float(raw_input("Enter weight:")) + graph[src][dst] = weight + +FloydWarshall(graph, V) diff --git a/data_structures/graph/graph.py b/data_structures/graph/graph.py new file mode 100644 index 000000000..9bd61559d --- /dev/null +++ b/data_structures/graph/graph.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +# encoding=utf8 + +from __future__ import print_function +# Author: OMKAR PATHAK + +# We can use Python's dictionary for constructing the graph + +class AdjacencyList(object): + def __init__(self): + self.List = {} + + def addEdge(self, fromVertex, toVertex): + # check if vertex is already present + if fromVertex in self.List.keys(): + self.List[fromVertex].append(toVertex) + else: + self.List[fromVertex] = [toVertex] + + def printList(self): + for i in self.List: + print((i,'->',' -> '.join([str(j) for j in self.List[i]]))) + +if __name__ == '__main__': + al = AdjacencyList() + al.addEdge(0, 1) + al.addEdge(0, 4) + al.addEdge(4, 1) + al.addEdge(4, 3) + al.addEdge(1, 0) + al.addEdge(1, 4) + al.addEdge(1, 3) + al.addEdge(1, 2) + al.addEdge(2, 3) + al.addEdge(3, 4) + + al.printList() + + # OUTPUT: + # 0 -> 1 -> 4 + # 1 -> 0 -> 4 -> 3 -> 2 + # 2 -> 3 + # 3 -> 4 + # 4 -> 1 -> 3 diff --git a/data_structures/graph/graph_list.py b/data_structures/graph/graph_list.py new file mode 100644 index 000000000..d67bc96c4 --- /dev/null +++ b/data_structures/graph/graph_list.py @@ -0,0 +1,31 @@ +from __future__ import print_function + + +class Graph: + def __init__(self, vertex): + self.vertex = vertex + self.graph = [[0] for i in range(vertex)] + + def add_edge(self, u, v): + self.graph[u - 1].append(v - 1) + + def show(self): + for i in range(self.vertex): + print('%d: '% (i + 1), end=' ') + for j in self.graph[i]: + print('%d-> '% (j + 1), end=' ') + print(' ') + + + +g = Graph(100) + +g.add_edge(1,3) +g.add_edge(2,3) +g.add_edge(3,4) +g.add_edge(3,5) +g.add_edge(4,5) + + +g.show() + diff --git a/data_structures/graph/graph_matrix.py b/data_structures/graph/graph_matrix.py new file mode 100644 index 000000000..de25301d6 --- /dev/null +++ b/data_structures/graph/graph_matrix.py @@ -0,0 +1,32 @@ +from __future__ import print_function + + +class Graph: + + def __init__(self, vertex): + self.vertex = vertex + self.graph = [[0] * vertex for i in range(vertex) ] + + def add_edge(self, u, v): + self.graph[u - 1][v - 1] = 1 + self.graph[v - 1][u - 1] = 1 + + def show(self): + + for i in self.graph: + for j in i: + print(j, end=' ') + print(' ') + + + + +g = Graph(100) + +g.add_edge(1,4) +g.add_edge(4,2) +g.add_edge(4,5) +g.add_edge(2,5) +g.add_edge(5,3) +g.show() + diff --git a/data_structures/heap/heap.py b/data_structures/heap/heap.py new file mode 100644 index 000000000..d0c2400eb --- /dev/null +++ b/data_structures/heap/heap.py @@ -0,0 +1,90 @@ +#!/usr/bin/python + +from __future__ import print_function, division + +try: + raw_input # Python 2 +except NameError: + raw_input = input # Python 3 + +class Heap: + def __init__(self): + self.h = [] + self.currsize = 0 + + def leftChild(self,i): + if 2*i+1 < self.currsize: + return 2*i+1 + return None + + def rightChild(self,i): + if 2*i+2 < self.currsize: + return 2*i+2 + return None + + def maxHeapify(self,node): + if node < self.currsize: + m = node + lc = self.leftChild(node) + rc = self.rightChild(node) + if lc is not None and self.h[lc] > self.h[m]: + m = lc + if rc is not None and self.h[rc] > self.h[m]: + m = rc + if m!=node: + temp = self.h[node] + self.h[node] = self.h[m] + self.h[m] = temp + self.maxHeapify(m) + + def buildHeap(self,a): + self.currsize = len(a) + self.h = list(a) + for i in range(self.currsize/2,-1,-1): + self.maxHeapify(i) + + def getMax(self): + if self.currsize >= 1: + me = self.h[0] + temp = self.h[0] + self.h[0] = self.h[self.currsize-1] + self.h[self.currsize-1] = temp + self.currsize -= 1 + self.maxHeapify(0) + return me + return None + + def heapSort(self): + size = self.currsize + while self.currsize-1 >= 0: + temp = self.h[0] + self.h[0] = self.h[self.currsize-1] + self.h[self.currsize-1] = temp + self.currsize -= 1 + self.maxHeapify(0) + self.currsize = size + + def insert(self,data): + self.h.append(data) + curr = self.currsize + self.currsize+=1 + while self.h[curr] > self.h[curr/2]: + temp = self.h[curr/2] + self.h[curr/2] = self.h[curr] + self.h[curr] = temp + curr = curr/2 + + def display(self): + print(self.h) + +def main(): + l = list(map(int, raw_input().split())) + h = Heap() + h.buildHeap(l) + h.heapSort() + h.display() + +if __name__=='__main__': + main() + + diff --git a/data_structures/linked_list/DoublyLinkedList.py b/data_structures/linked_list/DoublyLinkedList.py new file mode 100644 index 000000000..18eb63fea --- /dev/null +++ b/data_structures/linked_list/DoublyLinkedList.py @@ -0,0 +1,76 @@ +''' +- A linked list is similar to an array, it holds values. However, links in a linked list do not have indexes. +- This is an example of a double ended, doubly linked list. +- Each link references the next link and the previous one. +''' +from __future__ import print_function + + +class LinkedList: + def __init__(self): + self.head = None + self.tail = None + + def insertHead(self, x): + newLink = Link(x) #Create a new link with a value attached to it + if(self.isEmpty() == True): #Set the first element added to be the tail + self.tail = newLink + else: + self.head.previous = newLink # newLink <-- currenthead(head) + newLink.next = self.head # newLink <--> currenthead(head) + self.head = newLink # newLink(head) <--> oldhead + + def deleteHead(self): + temp = self.head + self.head = self.head.next # oldHead <--> 2ndElement(head) + self.head.previous = None # oldHead --> 2ndElement(head) nothing pointing at it so the old head will be removed + if(self.head is None): + self.tail = None + return temp + + def insertTail(self, x): + newLink = Link(x) + newLink.next = None # currentTail(tail) newLink --> + self.tail.next = newLink # currentTail(tail) --> newLink --> + newLink.previous = self.tail #currentTail(tail) <--> newLink --> + self.tail = newLink # oldTail <--> newLink(tail) --> + + def deleteTail(self): + temp = self.tail + self.tail = self.tail.previous # 2ndLast(tail) <--> oldTail --> None + self.tail.next = None # 2ndlast(tail) --> None + return temp + + def delete(self, x): + current = self.head + + while(current.value != x): # Find the position to delete + current = current.next + + if(current == self.head): + self.deleteHead() + + elif(current == self.tail): + self.deleteTail() + + else: #Before: 1 <--> 2(current) <--> 3 + current.previous.next = current.next # 1 --> 3 + current.next.previous = current.previous # 1 <--> 3 + + def isEmpty(self): #Will return True if the list is empty + return(self.head is None) + + def display(self): #Prints contents of the list + current = self.head + while(current != None): + current.displayLink() + current = current.next + print() + +class Link: + next = None #This points to the link in front of the new link + previous = None #This points to the link behind the new link + def __init__(self, x): + self.value = x + def displayLink(self): + print("{}".format(self.value), end=" ") diff --git a/data_structures/linked_list/__init__.py b/data_structures/linked_list/__init__.py new file mode 100644 index 000000000..6d50f23c1 --- /dev/null +++ b/data_structures/linked_list/__init__.py @@ -0,0 +1,22 @@ +class Node: + def __init__(self, item, next): + self.item = item + self.next = next + +class LinkedList: + def __init__(self): + self.head = None + + def add(self, item): + self.head = Node(item, self.head) + + def remove(self): + if self.is_empty(): + return None + else: + item = self.head.item + self.head = self.head.next + return item + + def is_empty(self): + return self.head is None diff --git a/data_structures/linked_list/singly_LinkedList.py b/data_structures/linked_list/singly_LinkedList.py new file mode 100644 index 000000000..0d6157e3e --- /dev/null +++ b/data_structures/linked_list/singly_LinkedList.py @@ -0,0 +1,70 @@ +from __future__ import print_function + + +class Node: # create a Node + def __init__(self, data): + self.data = data # given data + self.next = None # given next to None + + +class Linked_List: + def insert_tail(Head, data): + if Head.next is None: + Head.next = Node(data) + else: + Head.next.insert_tail(data) + + def insert_head(Head, data): + tamp = Head + if tamp is None: + newNod = Node() # create a new Node + newNod.data = data + newNod.next = None + Head = newNod # make new node to Head + else: + newNod = Node() + newNod.data = data + newNod.next = Head # put the Head at NewNode Next + Head = newNod # make a NewNode to Head + return Head + + def printList(Head): # print every node data + tamp = Head + while tamp is not None: + print(tamp.data) + tamp = tamp.next + + def delete_head(Head): # delete from head + if Head is not None: + Head = Head.next + return Head # return new Head + + def delete_tail(Head): # delete from tail + if Head is not None: + tamp = Node() + tamp = Head + while tamp.next.next is not None: # find the 2nd last element + tamp = tamp.next + # delete the last element by give next None to 2nd last Element + tamp.next = None + return Head + + def isEmpty(Head): + return Head is None # Return if Head is none + + def reverse(Head): + prev = None + current = Head + + while current: + # Store the current node's next node. + next_node = current.next + # Make the current node's next point backwards + current.next = prev + # Make the previous node be the current node + prev = current + # Make the current node the next node (to progress iteration) + current = next_node + # Return prev in order to put the head at the end + Head = prev + return Head diff --git a/data_structures/queue/DeQueue.py b/data_structures/queue/DeQueue.py new file mode 100644 index 000000000..fdee64eb6 --- /dev/null +++ b/data_structures/queue/DeQueue.py @@ -0,0 +1,40 @@ +from __future__ import print_function +# Python code to demonstrate working of +# extend(), extendleft(), rotate(), reverse() + +# importing "collections" for deque operations +import collections + +# initializing deque +de = collections.deque([1, 2, 3,]) + +# using extend() to add numbers to right end +# adds 4,5,6 to right end +de.extend([4,5,6]) + +# printing modified deque +print ("The deque after extending deque at end is : ") +print (de) + +# using extendleft() to add numbers to left end +# adds 7,8,9 to right end +de.extendleft([7,8,9]) + +# printing modified deque +print ("The deque after extending deque at beginning is : ") +print (de) + +# using rotate() to rotate the deque +# rotates by 3 to left +de.rotate(-3) + +# printing modified deque +print ("The deque after rotating deque is : ") +print (de) + +# using reverse() to reverse the deque +de.reverse() + +# printing modified deque +print ("The deque after reversing deque is : ") +print (de) diff --git a/data_structures/queue/QueueOnList.py b/data_structures/queue/QueueOnList.py new file mode 100644 index 000000000..c8d0b41de --- /dev/null +++ b/data_structures/queue/QueueOnList.py @@ -0,0 +1,45 @@ +"""Queue represented by a python list""" +class Queue(): + def __init__(self): + self.entries = [] + self.length = 0 + self.front=0 + + def __str__(self): + printed = '<' + str(self.entries)[1:-1] + '>' + return printed + + """Enqueues {@code item} + @param item + item to enqueue""" + def put(self, item): + self.entries.append(item) + self.length = self.length + 1 + + + """Dequeues {@code item} + @requirement: |self.length| > 0 + @return dequeued + item that was dequeued""" + def get(self): + self.length = self.length - 1 + dequeued = self.entries[self.front] + self.front-=1 + self.entries = self.entries[self.front:] + return dequeued + + """Rotates the queue {@code rotation} times + @param rotation + number of times to rotate queue""" + def rotate(self, rotation): + for i in range(rotation): + self.put(self.get()) + + """Enqueues {@code item} + @return item at front of self.entries""" + def front(self): + return self.entries[0] + + """Returns the length of this.entries""" + def size(self): + return self.length diff --git a/data_structures/queue/QueueOnPseudoStack.py b/data_structures/queue/QueueOnPseudoStack.py new file mode 100644 index 000000000..b69fbcc98 --- /dev/null +++ b/data_structures/queue/QueueOnPseudoStack.py @@ -0,0 +1,50 @@ +"""Queue represented by a pseudo stack (represented by a list with pop and append)""" +class Queue(): + def __init__(self): + self.stack = [] + self.length = 0 + + def __str__(self): + printed = '<' + str(self.stack)[1:-1] + '>' + return printed + + """Enqueues {@code item} + @param item + item to enqueue""" + def put(self, item): + self.stack.append(item) + self.length = self.length + 1 + + """Dequeues {@code item} + @requirement: |self.length| > 0 + @return dequeued + item that was dequeued""" + def get(self): + self.rotate(1) + dequeued = self.stack[self.length-1] + self.stack = self.stack[:-1] + self.rotate(self.length-1) + self.length = self.length -1 + return dequeued + + """Rotates the queue {@code rotation} times + @param rotation + number of times to rotate queue""" + def rotate(self, rotation): + for i in range(rotation): + temp = self.stack[0] + self.stack = self.stack[1:] + self.put(temp) + self.length = self.length - 1 + + """Reports item at the front of self + @return item at front of self.stack""" + def front(self): + front = self.get() + self.put(front) + self.rotate(self.length-1) + return front + + """Returns the length of this.stack""" + def size(self): + return self.length diff --git a/data_structures/queue/__init__.py b/data_structures/queue/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/data_structures/stacks/Stock-Span-Problem.py b/data_structures/stacks/Stock-Span-Problem.py new file mode 100644 index 000000000..9628864ed --- /dev/null +++ b/data_structures/stacks/Stock-Span-Problem.py @@ -0,0 +1,52 @@ +''' +The stock span problem is a financial problem where we have a series of n daily +price quotes for a stock and we need to calculate span of stock's price for all n days. + +The span Si of the stock's price on a given day i is defined as the maximum +number of consecutive days just before the given day, for which the price of the stock +on the current day is less than or equal to its price on the given day. +''' +from __future__ import print_function +def calculateSpan(price, S): + + n = len(price) + # Create a stack and push index of fist element to it + st = [] + st.append(0) + + # Span value of first element is always 1 + S[0] = 1 + + # Calculate span values for rest of the elements + for i in range(1, n): + + # Pop elements from stack whlie stack is not + # empty and top of stack is smaller than price[i] + while( len(st) > 0 and price[st[0]] <= price[i]): + st.pop() + + # If stack becomes empty, then price[i] is greater + # than all elements on left of it, i.e. price[0], + # price[1], ..price[i-1]. Else the price[i] is + # greater than elements after top of stack + S[i] = i+1 if len(st) <= 0 else (i - st[0]) + + # Push this element to stack + st.append(i) + + +# A utility function to print elements of array +def printArray(arr, n): + for i in range(0,n): + print (arr[i],end =" ") + + +# Driver program to test above function +price = [10, 4, 5, 90, 120, 80] +S = [0 for i in range(len(price)+1)] + +# Fill the span values in array S[] +calculateSpan(price, S) + +# Print the calculated span values +printArray(S, len(price)) diff --git a/data_structures/stacks/__init__.py b/data_structures/stacks/__init__.py new file mode 100644 index 000000000..f7e92ae2d --- /dev/null +++ b/data_structures/stacks/__init__.py @@ -0,0 +1,23 @@ +class Stack: + + def __init__(self): + self.stack = [] + self.top = 0 + + def is_empty(self): + return (self.top == 0) + + def push(self, item): + if self.top < len(self.stack): + self.stack[self.top] = item + else: + self.stack.append(item) + + self.top += 1 + + def pop(self): + if self.is_empty(): + return None + else: + self.top -= 1 + return self.stack[self.top] diff --git a/data_structures/stacks/balanced_parentheses.py b/data_structures/stacks/balanced_parentheses.py new file mode 100644 index 000000000..8d99358be --- /dev/null +++ b/data_structures/stacks/balanced_parentheses.py @@ -0,0 +1,23 @@ +from __future__ import print_function +from __future__ import absolute_import +from .Stack import Stack + +__author__ = 'Omkar Pathak' + + +def balanced_parentheses(parentheses): + """ Use a stack to check if a string of parentheses are balanced.""" + stack = Stack(len(parentheses)) + for parenthesis in parentheses: + if parenthesis == '(': + stack.push(parenthesis) + elif parenthesis == ')': + stack.pop() + return not stack.is_empty() + + +if __name__ == '__main__': + examples = ['((()))', '((())'] + print('Balanced parentheses demonstration:\n') + for example in examples: + print(example + ': ' + str(balanced_parentheses(example))) diff --git a/data_structures/stacks/infix_to_postfix_conversion.py b/data_structures/stacks/infix_to_postfix_conversion.py new file mode 100644 index 000000000..75211fed2 --- /dev/null +++ b/data_structures/stacks/infix_to_postfix_conversion.py @@ -0,0 +1,64 @@ +from __future__ import print_function +from __future__ import absolute_import +import string + +from .Stack import Stack + +__author__ = 'Omkar Pathak' + + +def is_operand(char): + return char in string.ascii_letters or char in string.digits + + +def precedence(char): + """ Return integer value representing an operator's precedence, or + order of operation. + + https://en.wikipedia.org/wiki/Order_of_operations + """ + dictionary = {'+': 1, '-': 1, + '*': 2, '/': 2, + '^': 3} + return dictionary.get(char, -1) + + +def infix_to_postfix(expression): + """ Convert infix notation to postfix notation using the Shunting-yard + algorithm. + + https://en.wikipedia.org/wiki/Shunting-yard_algorithm + https://en.wikipedia.org/wiki/Infix_notation + https://en.wikipedia.org/wiki/Reverse_Polish_notation + """ + stack = Stack(len(expression)) + postfix = [] + for char in expression: + if is_operand(char): + postfix.append(char) + elif char not in {'(', ')'}: + while (not stack.is_empty() + and precedence(char) <= precedence(stack.peek())): + postfix.append(stack.pop()) + stack.push(char) + elif char == '(': + stack.push(char) + elif char == ')': + while not stack.is_empty() and stack.peek() != '(': + postfix.append(stack.pop()) + # Pop '(' from stack. If there is no '(', there is a mismatched + # parentheses. + if stack.peek() != '(': + raise ValueError('Mismatched parentheses') + stack.pop() + while not stack.is_empty(): + postfix.append(stack.pop()) + return ' '.join(postfix) + + +if __name__ == '__main__': + expression = 'a+b*(c^d-e)^(f+g*h)-i' + + print('Infix to Postfix Notation demonstration:\n') + print('Infix notation: ' + expression) + print('Postfix notation: ' + infix_to_postfix(expression)) diff --git a/data_structures/stacks/next.py b/data_structures/stacks/next.py new file mode 100644 index 000000000..bca833395 --- /dev/null +++ b/data_structures/stacks/next.py @@ -0,0 +1,17 @@ +from __future__ import print_function +# Function to print element and NGE pair for all elements of list +def printNGE(arr): + + for i in range(0, len(arr), 1): + + next = -1 + for j in range(i+1, len(arr), 1): + if arr[i] < arr[j]: + next = arr[j] + break + + print(str(arr[i]) + " -- " + str(next)) + +# Driver program to test above function +arr = [11,13,21,3] +printNGE(arr) diff --git a/data_structures/stacks/stack.py b/data_structures/stacks/stack.py new file mode 100644 index 000000000..66af8c025 --- /dev/null +++ b/data_structures/stacks/stack.py @@ -0,0 +1,69 @@ +from __future__ import print_function +__author__ = 'Omkar Pathak' + + +class Stack(object): + """ A stack is an abstract data type that serves as a collection of + elements with two principal operations: push() and pop(). push() adds an + element to the top of the stack, and pop() removes an element from the top + of a stack. The order in which elements come off of a stack are + Last In, First Out (LIFO). + + https://en.wikipedia.org/wiki/Stack_(abstract_data_type) + """ + + def __init__(self, limit=10): + self.stack = [] + self.limit = limit + + def __bool__(self): + return not bool(self.stack) + + def __str__(self): + return str(self.stack) + + def push(self, data): + """ Push an element to the top of the stack.""" + if len(self.stack) >= self.limit: + raise StackOverflowError + self.stack.append(data) + + def pop(self): + """ Pop an element off of the top of the stack.""" + if self.stack: + return self.stack.pop() + else: + raise IndexError('pop from an empty stack') + + def peek(self): + """ Peek at the top-most element of the stack.""" + if self.stack: + return self.stack[-1] + + def is_empty(self): + """ Check if a stack is empty.""" + return not bool(self.stack) + + def size(self): + """ Return the size of the stack.""" + return len(self.stack) + + +class StackOverflowError(BaseException): + pass + + +if __name__ == '__main__': + stack = Stack() + for i in range(10): + stack.push(i) + + print('Stack demonstration:\n') + print('Initial stack: ' + str(stack)) + print('pop(): ' + str(stack.pop())) + print('After pop(), the stack is now: ' + str(stack)) + print('peek(): ' + str(stack.peek())) + stack.push(100) + print('After push(100), the stack is now: ' + str(stack)) + print('is_empty(): ' + str(stack.is_empty())) + print('size(): ' + str(stack.size())) diff --git a/data_structures/trie/Trie.py b/data_structures/trie/Trie.py new file mode 100644 index 000000000..b6234c670 --- /dev/null +++ b/data_structures/trie/Trie.py @@ -0,0 +1,75 @@ +""" +A Trie/Prefix Tree is a kind of search tree used to provide quick lookup +of words/patterns in a set of words. A basic Trie however has O(n^2) space complexity +making it impractical in practice. It however provides O(max(search_string, length of longest word)) lookup +time making it an optimal approach when space is not an issue. + +""" + + +class TrieNode: + def __init__(self): + self.nodes = dict() # Mapping from char to TrieNode + self.is_leaf = False + + def insert_many(self, words: [str]): # noqa: E999 This syntax is Python 3 only + """ + Inserts a list of words into the Trie + :param words: list of string words + :return: None + """ + for word in words: + self.insert(word) + + def insert(self, word: str): # noqa: E999 This syntax is Python 3 only + """ + Inserts a word into the Trie + :param word: word to be inserted + :return: None + """ + curr = self + for char in word: + if char not in curr.nodes: + curr.nodes[char] = TrieNode() + curr = curr.nodes[char] + curr.is_leaf = True + + def find(self, word: str) -> bool: # noqa: E999 This syntax is Python 3 only + """ + Tries to find word in a Trie + :param word: word to look for + :return: Returns True if word is found, False otherwise + """ + curr = self + for char in word: + if char not in curr.nodes: + return False + curr = curr.nodes[char] + return curr.is_leaf + + +def print_words(node: TrieNode, word: str): # noqa: E999 This syntax is Python 3 only + """ + Prints all the words in a Trie + :param node: root node of Trie + :param word: Word variable should be empty at start + :return: None + """ + if node.is_leaf: + print(word, end=' ') + + for key, value in node.nodes.items(): + print_words(value, word + key) + + +def test(): + words = ['banana', 'bananas', 'bandana', 'band', 'apple', 'all', 'beast'] + root = TrieNode() + root.insert_many(words) + # print_words(root, '') + assert root.find('banana') + assert not root.find('bandanas') + assert not root.find('apps') + assert root.find('apple') + +test() diff --git a/data_structures/union_find/__init__.py b/data_structures/union_find/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/data_structures/union_find/tests_union_find.py b/data_structures/union_find/tests_union_find.py new file mode 100644 index 000000000..b0708778d --- /dev/null +++ b/data_structures/union_find/tests_union_find.py @@ -0,0 +1,78 @@ +from __future__ import absolute_import +from .union_find import UnionFind +import unittest + + +class TestUnionFind(unittest.TestCase): + def test_init_with_valid_size(self): + uf = UnionFind(5) + self.assertEqual(uf.size, 5) + + def test_init_with_invalid_size(self): + with self.assertRaises(ValueError): + uf = UnionFind(0) + + with self.assertRaises(ValueError): + uf = UnionFind(-5) + + def test_union_with_valid_values(self): + uf = UnionFind(10) + + for i in range(11): + for j in range(11): + uf.union(i, j) + + def test_union_with_invalid_values(self): + uf = UnionFind(10) + + with self.assertRaises(ValueError): + uf.union(-1, 1) + + with self.assertRaises(ValueError): + uf.union(11, 1) + + def test_same_set_with_valid_values(self): + uf = UnionFind(10) + + for i in range(11): + for j in range(11): + if i == j: + self.assertTrue(uf.same_set(i, j)) + else: + self.assertFalse(uf.same_set(i, j)) + + uf.union(1, 2) + self.assertTrue(uf.same_set(1, 2)) + + uf.union(3, 4) + self.assertTrue(uf.same_set(3, 4)) + + self.assertFalse(uf.same_set(1, 3)) + self.assertFalse(uf.same_set(1, 4)) + self.assertFalse(uf.same_set(2, 3)) + self.assertFalse(uf.same_set(2, 4)) + + uf.union(1, 3) + self.assertTrue(uf.same_set(1, 3)) + self.assertTrue(uf.same_set(1, 4)) + self.assertTrue(uf.same_set(2, 3)) + self.assertTrue(uf.same_set(2, 4)) + + uf.union(4, 10) + self.assertTrue(uf.same_set(1, 10)) + self.assertTrue(uf.same_set(2, 10)) + self.assertTrue(uf.same_set(3, 10)) + self.assertTrue(uf.same_set(4, 10)) + + def test_same_set_with_invalid_values(self): + uf = UnionFind(10) + + with self.assertRaises(ValueError): + uf.same_set(-1, 1) + + with self.assertRaises(ValueError): + uf.same_set(11, 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/data_structures/union_find/union_find.py b/data_structures/union_find/union_find.py new file mode 100644 index 000000000..40eea67ac --- /dev/null +++ b/data_structures/union_find/union_find.py @@ -0,0 +1,87 @@ +class UnionFind(): + """ + https://en.wikipedia.org/wiki/Disjoint-set_data_structure + + The union-find is a disjoint-set data structure + + You can merge two sets and tell if one set belongs to + another one. + + It's used on the Kruskal Algorithm + (https://en.wikipedia.org/wiki/Kruskal%27s_algorithm) + + The elements are in range [0, size] + """ + def __init__(self, size): + if size <= 0: + raise ValueError("size should be greater than 0") + + self.size = size + + # The below plus 1 is because we are using elements + # in range [0, size]. It makes more sense. + + # Every set begins with only itself + self.root = [i for i in range(size+1)] + + # This is used for heuristic union by rank + self.weight = [0 for i in range(size+1)] + + def union(self, u, v): + """ + Union of the sets u and v. + Complexity: log(n). + Amortized complexity: < 5 (it's very fast). + """ + + self._validate_element_range(u, "u") + self._validate_element_range(v, "v") + + if u == v: + return + + # Using union by rank will guarantee the + # log(n) complexity + rootu = self._root(u) + rootv = self._root(v) + weight_u = self.weight[rootu] + weight_v = self.weight[rootv] + if weight_u >= weight_v: + self.root[rootv] = rootu + if weight_u == weight_v: + self.weight[rootu] += 1 + else: + self.root[rootu] = rootv + + def same_set(self, u, v): + """ + Return true if the elements u and v belongs to + the same set + """ + + self._validate_element_range(u, "u") + self._validate_element_range(v, "v") + + return self._root(u) == self._root(v) + + def _root(self, u): + """ + Get the element set root. + This uses the heuristic path compression + See wikipedia article for more details. + """ + + if u != self.root[u]: + self.root[u] = self._root(self.root[u]) + + return self.root[u] + + def _validate_element_range(self, u, element_name): + """ + Raises ValueError if element is not in range + """ + if u < 0 or u > self.size: + msg = ("element {0} with value {1} " + "should be in range [0~{2}]")\ + .format(element_name, u, self.size) + raise ValueError(msg) diff --git a/dynamic_programming/floyd_warshall.py b/dynamic_programming/floyd_warshall.py new file mode 100644 index 000000000..038499ca0 --- /dev/null +++ b/dynamic_programming/floyd_warshall.py @@ -0,0 +1,37 @@ +import math + +class Graph: + + def __init__(self, N = 0): # a graph with Node 0,1,...,N-1 + self.N = N + self.W = [[math.inf for j in range(0,N)] for i in range(0,N)] # adjacency matrix for weight + self.dp = [[math.inf for j in range(0,N)] for i in range(0,N)] # dp[i][j] stores minimum distance from i to j + + def addEdge(self, u, v, w): + self.dp[u][v] = w + + def floyd_warshall(self): + for k in range(0,self.N): + for i in range(0,self.N): + for j in range(0,self.N): + self.dp[i][j] = min(self.dp[i][j], self.dp[i][k] + self.dp[k][j]) + + def showMin(self, u, v): + return self.dp[u][v] + +if __name__ == '__main__': + graph = Graph(5) + graph.addEdge(0,2,9) + graph.addEdge(0,4,10) + graph.addEdge(1,3,5) + graph.addEdge(2,3,7) + graph.addEdge(3,0,10) + graph.addEdge(3,1,2) + graph.addEdge(3,2,1) + graph.addEdge(3,4,6) + graph.addEdge(4,1,3) + graph.addEdge(4,2,4) + graph.addEdge(4,3,9) + graph.floyd_warshall() + graph.showMin(1,4) + graph.showMin(0,3) diff --git a/file_transfer_protocol/ftp_client_server.py b/file_transfer_protocol/ftp_client_server.py new file mode 100644 index 000000000..f73f85843 --- /dev/null +++ b/file_transfer_protocol/ftp_client_server.py @@ -0,0 +1,58 @@ +# server + +import socket # Import socket module + +port = 60000 # Reserve a port for your service. +s = socket.socket() # Create a socket object +host = socket.gethostname() # Get local machine name +s.bind((host, port)) # Bind to the port +s.listen(5) # Now wait for client connection. + +print('Server listening....') + +while True: + conn, addr = s.accept() # Establish connection with client. + print('Got connection from', addr) + data = conn.recv(1024) + print('Server received', repr(data)) + + filename = 'mytext.txt' + f = open(filename, 'rb') + in_data = f.read(1024) + while (in_data): + conn.send(in_data) + print('Sent ', repr(in_data)) + in_data = f.read(1024) + f.close() + + print('Done sending') + conn.send('Thank you for connecting') + conn.close() + + +# client side server + +import socket # Import socket module + +s = socket.socket() # Create a socket object +host = socket.gethostname() # Get local machine name +port = 60000 # Reserve a port for your service. + +s.connect((host, port)) +s.send("Hello server!") + +with open('received_file', 'wb') as f: + print('file opened') + while True: + print('receiving data...') + data = s.recv(1024) + print('data=%s', (data)) + if not data: + break + # write data to a file + f.write(data) + +f.close() +print('Successfully get the file') +s.close() +print('connection closed') diff --git a/file_transfer_protocol/ftp_send_receive.py b/file_transfer_protocol/ftp_send_receive.py new file mode 100644 index 000000000..d4919158a --- /dev/null +++ b/file_transfer_protocol/ftp_send_receive.py @@ -0,0 +1,36 @@ +""" + File transfer protocol used to send and receive files using FTP server. + Use credentials to provide access to the FTP client + + Note: Do not use root username & password for security reasons + Create a seperate user and provide access to a home directory of the user + Use login id and password of the user created + cwd here stands for current working directory +""" + +from ftplib import FTP +ftp = FTP('xxx.xxx.x.x') # Enter the ip address or the domain name here +ftp.login(user='username', passwd='password') +ftp.cwd('/Enter the directory here/') + +""" + The file which will be received via the FTP server + Enter the location of the file where the file is received +""" + +def ReceiveFile(): + FileName = 'example.txt' """ Enter the location of the file """ + LocalFile = open(FileName, 'wb') + ftp.retrbinary('RETR ' + FileName, LocalFile.write, 1024) + ftp.quit() + LocalFile.close() + +""" + The file which will be sent via the FTP server + The file send will be send to the current working directory +""" + +def SendFile(): + FileName = 'example.txt' """ Enter the name of the file """ + ftp.storbinary('STOR ' + FileName, open(FileName, 'rb')) + ftp.quit() diff --git a/graphs/ArticulationPoints.py b/graphs/ArticulationPoints.py new file mode 100644 index 000000000..1173c4ea3 --- /dev/null +++ b/graphs/ArticulationPoints.py @@ -0,0 +1,44 @@ +# Finding Articulation Points in Undirected Graph +def computeAP(l): + n = len(l) + outEdgeCount = 0 + low = [0] * n + visited = [False] * n + isArt = [False] * n + + def dfs(root, at, parent, outEdgeCount): + if parent == root: + outEdgeCount += 1 + visited[at] = True + low[at] = at + + for to in l[at]: + if to == parent: + pass + elif not visited[to]: + outEdgeCount = dfs(root, to, at, outEdgeCount) + low[at] = min(low[at], low[to]) + + # AP found via bridge + if at < low[to]: + isArt[at] = True + # AP found via cycle + if at == low[to]: + isArt[at] = True + else: + low[at] = min(low[at], to) + return outEdgeCount + + for i in range(n): + if not visited[i]: + outEdgeCount = 0 + outEdgeCount = dfs(i, i, -1, outEdgeCount) + isArt[i] = (outEdgeCount > 1) + + for x in range(len(isArt)): + if isArt[x] == True: + print(x) + +# Adjacency list of graph +l = {0:[1,2], 1:[0,2], 2:[0,1,3,5], 3:[2,4], 4:[3], 5:[2,6,8], 6:[5,7], 7:[6,8], 8:[5,7]} +computeAP(l) diff --git a/graphs/CheckBipartiteGraph_BFS.py b/graphs/CheckBipartiteGraph_BFS.py new file mode 100644 index 000000000..1b9c32c6c --- /dev/null +++ b/graphs/CheckBipartiteGraph_BFS.py @@ -0,0 +1,43 @@ +# Check whether Graph is Bipartite or Not using BFS + +# A Bipartite Graph is a graph whose vertices can be divided into two independent sets, +# U and V such that every edge (u, v) either connects a vertex from U to V or a vertex +# from V to U. In other words, for every edge (u, v), either u belongs to U and v to V, +# or u belongs to V and v to U. We can also say that there is no edge that connects +# vertices of same set. +def checkBipartite(l): + queue = [] + visited = [False] * len(l) + color = [-1] * len(l) + + def bfs(): + while(queue): + u = queue.pop(0) + visited[u] = True + + for neighbour in l[u]: + + if neighbour == u: + return False + + if color[neighbour] == -1: + color[neighbour] = 1 - color[u] + queue.append(neighbour) + + elif color[neighbour] == color[u]: + return False + + return True + + for i in range(len(l)): + if not visited[i]: + queue.append(i) + color[i] = 0 + if bfs() == False: + return False + + return True + +# Adjacency List of graph +l = {0:[1,3], 1:[0,2], 2:[1,3], 3:[0,2]} +print(checkBipartite(l)) diff --git a/graphs/FindingBridges.py b/graphs/FindingBridges.py new file mode 100644 index 000000000..56533dd48 --- /dev/null +++ b/graphs/FindingBridges.py @@ -0,0 +1,31 @@ +# Finding Bridges in Undirected Graph +def computeBridges(l): + id = 0 + n = len(l) # No of vertices in graph + low = [0] * n + visited = [False] * n + + def dfs(at, parent, bridges, id): + visited[at] = True + low[at] = id + id += 1 + for to in l[at]: + if to == parent: + pass + elif not visited[to]: + dfs(to, at, bridges, id) + low[at] = min(low[at], low[to]) + if at < low[to]: + bridges.append([at, to]) + else: + # This edge is a back edge and cannot be a bridge + low[at] = min(low[at], to) + + bridges = [] + for i in range(n): + if (not visited[i]): + dfs(i, -1, bridges, id) + print(bridges) + +l = {0:[1,2], 1:[0,2], 2:[0,1,3,5], 3:[2,4], 4:[3], 5:[2,6,8], 6:[5,7], 7:[6,8], 8:[5,7]} +computeBridges(l) diff --git a/graphs/KahnsAlgorithm_long.py b/graphs/KahnsAlgorithm_long.py new file mode 100644 index 000000000..453b5706f --- /dev/null +++ b/graphs/KahnsAlgorithm_long.py @@ -0,0 +1,30 @@ +# Finding longest distance in Directed Acyclic Graph using KahnsAlgorithm +def longestDistance(l): + indegree = [0] * len(l) + queue = [] + longDist = [1] * len(l) + + for key, values in l.items(): + for i in values: + indegree[i] += 1 + + for i in range(len(indegree)): + if indegree[i] == 0: + queue.append(i) + + while(queue): + vertex = queue.pop(0) + for x in l[vertex]: + indegree[x] -= 1 + + if longDist[vertex] + 1 > longDist[x]: + longDist[x] = longDist[vertex] + 1 + + if indegree[x] == 0: + queue.append(x) + + print(max(longDist)) + +# Adjacency list of Graph +l = {0:[2,3,4], 1:[2,7], 2:[5], 3:[5,7], 4:[7], 5:[6], 6:[7], 7:[]} +longestDistance(l) diff --git a/graphs/KahnsAlgorithm_topo.py b/graphs/KahnsAlgorithm_topo.py new file mode 100644 index 000000000..8c182c4e9 --- /dev/null +++ b/graphs/KahnsAlgorithm_topo.py @@ -0,0 +1,32 @@ +# Kahn's Algorithm is used to find Topological ordering of Directed Acyclic Graph using BFS +def topologicalSort(l): + indegree = [0] * len(l) + queue = [] + topo = [] + cnt = 0 + + for key, values in l.items(): + for i in values: + indegree[i] += 1 + + for i in range(len(indegree)): + if indegree[i] == 0: + queue.append(i) + + while(queue): + vertex = queue.pop(0) + cnt += 1 + topo.append(vertex) + for x in l[vertex]: + indegree[x] -= 1 + if indegree[x] == 0: + queue.append(x) + + if cnt != len(l): + print("Cycle exists") + else: + print(topo) + +# Adjacency List of Graph +l = {0:[1,2], 1:[3], 2:[3], 3:[4,5], 4:[], 5:[]} +topologicalSort(l) diff --git a/graphs/MinimumSpanningTree_Prims.py b/graphs/MinimumSpanningTree_Prims.py new file mode 100644 index 000000000..569e73e0a --- /dev/null +++ b/graphs/MinimumSpanningTree_Prims.py @@ -0,0 +1,111 @@ +import sys +from collections import defaultdict + +def PrimsAlgorithm(l): + + nodePosition = [] + def getPosition(vertex): + return nodePosition[vertex] + + def setPosition(vertex, pos): + nodePosition[vertex] = pos + + def topToBottom(heap, start, size, positions): + if start > size // 2 - 1: + return + else: + if 2 * start + 2 >= size: + m = 2 * start + 1 + else: + if heap[2 * start + 1] < heap[2 * start + 2]: + m = 2 * start + 1 + else: + m = 2 * start + 2 + if heap[m] < heap[start]: + temp, temp1 = heap[m], positions[m] + heap[m], positions[m] = heap[start], positions[start] + heap[start], positions[start] = temp, temp1 + + temp = getPosition(positions[m]) + setPosition(positions[m], getPosition(positions[start])) + setPosition(positions[start], temp) + + topToBottom(heap, m, size, positions) + + # Update function if value of any node in min-heap decreases + def bottomToTop(val, index, heap, position): + temp = position[index] + + while(index != 0): + if index % 2 == 0: + parent = int( (index-2) / 2 ) + else: + parent = int( (index-1) / 2 ) + + if val < heap[parent]: + heap[index] = heap[parent] + position[index] = position[parent] + setPosition(position[parent], index) + else: + heap[index] = val + position[index] = temp + setPosition(temp, index) + break + index = parent + else: + heap[0] = val + position[0] = temp + setPosition(temp, 0) + + def heapify(heap, positions): + start = len(heap) // 2 - 1 + for i in range(start, -1, -1): + topToBottom(heap, i, len(heap), positions) + + def deleteMinimum(heap, positions): + temp = positions[0] + heap[0] = sys.maxsize + topToBottom(heap, 0, len(heap), positions) + return temp + + visited = [0 for i in range(len(l))] + Nbr_TV = [-1 for i in range(len(l))] # Neighboring Tree Vertex of selected vertex + # Minimum Distance of explored vertex with neighboring vertex of partial tree formed in graph + Distance_TV = [] # Heap of Distance of vertices from their neighboring vertex + Positions = [] + + for x in range(len(l)): + p = sys.maxsize + Distance_TV.append(p) + Positions.append(x) + nodePosition.append(x) + + TreeEdges = [] + visited[0] = 1 + Distance_TV[0] = sys.maxsize + for x in l[0]: + Nbr_TV[ x[0] ] = 0 + Distance_TV[ x[0] ] = x[1] + heapify(Distance_TV, Positions) + + for i in range(1, len(l)): + vertex = deleteMinimum(Distance_TV, Positions) + if visited[vertex] == 0: + TreeEdges.append((Nbr_TV[vertex], vertex)) + visited[vertex] = 1 + for v in l[vertex]: + if visited[v[0]] == 0 and v[1] < Distance_TV[ getPosition(v[0]) ]: + Distance_TV[ getPosition(v[0]) ] = v[1] + bottomToTop(v[1], getPosition(v[0]), Distance_TV, Positions) + Nbr_TV[ v[0] ] = vertex + return TreeEdges + +# < --------- Prims Algorithm --------- > +n = int(raw_input("Enter number of vertices: ")) +e = int(raw_input("Enter number of edges: ")) +adjlist = defaultdict(list) +for x in range(e): + l = [int(x) for x in input().split()] + adjlist[l[0]].append([ l[1], l[2] ]) + adjlist[l[1]].append([ l[0], l[2] ]) +print(PrimsAlgorithm(adjlist)) diff --git a/graphs/Multi_Hueristic_Astar.py b/graphs/Multi_Hueristic_Astar.py new file mode 100644 index 000000000..1acd098f3 --- /dev/null +++ b/graphs/Multi_Hueristic_Astar.py @@ -0,0 +1,266 @@ +from __future__ import print_function +import heapq +import numpy as np + +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + + +class PriorityQueue: + def __init__(self): + self.elements = [] + self.set = set() + + def minkey(self): + if not self.empty(): + return self.elements[0][0] + else: + return float('inf') + + def empty(self): + return len(self.elements) == 0 + + def put(self, item, priority): + if item not in self.set: + heapq.heappush(self.elements, (priority, item)) + self.set.add(item) + else: + # update + # print("update", item) + temp = [] + (pri, x) = heapq.heappop(self.elements) + while x != item: + temp.append((pri, x)) + (pri, x) = heapq.heappop(self.elements) + temp.append((priority, item)) + for (pro, xxx) in temp: + heapq.heappush(self.elements, (pro, xxx)) + + def remove_element(self, item): + if item in self.set: + self.set.remove(item) + temp = [] + (pro, x) = heapq.heappop(self.elements) + while x != item: + temp.append((pro, x)) + (pro, x) = heapq.heappop(self.elements) + for (prito, yyy) in temp: + heapq.heappush(self.elements, (prito, yyy)) + + def top_show(self): + return self.elements[0][1] + + def get(self): + (priority, item) = heapq.heappop(self.elements) + self.set.remove(item) + return (priority, item) + +def consistent_hueristic(P, goal): + # euclidean distance + a = np.array(P) + b = np.array(goal) + return np.linalg.norm(a - b) + +def hueristic_2(P, goal): + # integer division by time variable + return consistent_hueristic(P, goal) // t + +def hueristic_1(P, goal): + # manhattan distance + return abs(P[0] - goal[0]) + abs(P[1] - goal[1]) + +def key(start, i, goal, g_function): + ans = g_function[start] + W1 * hueristics[i](start, goal) + return ans + +def do_something(back_pointer, goal, start): + grid = np.chararray((n, n)) + for i in range(n): + for j in range(n): + grid[i][j] = '*' + + for i in range(n): + for j in range(n): + if (j, (n-1)-i) in blocks: + grid[i][j] = "#" + + grid[0][(n-1)] = "-" + x = back_pointer[goal] + while x != start: + (x_c, y_c) = x + # print(x) + grid[(n-1)-y_c][x_c] = "-" + x = back_pointer[x] + grid[(n-1)][0] = "-" + + + for i in xrange(n): + for j in range(n): + if (i, j) == (0, n-1): + print(grid[i][j], end=' ') + print("<-- End position", end=' ') + else: + print(grid[i][j], end=' ') + print() + print("^") + print("Start position") + print() + print("# is an obstacle") + print("- is the path taken by algorithm") + print("PATH TAKEN BY THE ALGORITHM IS:-") + x = back_pointer[goal] + while x != start: + print(x, end=' ') + x = back_pointer[x] + print(x) + quit() + +def valid(p): + if p[0] < 0 or p[0] > n-1: + return False + if p[1] < 0 or p[1] > n-1: + return False + return True + +def expand_state(s, j, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer): + for itera in range(n_hueristic): + open_list[itera].remove_element(s) + # print("s", s) + # print("j", j) + (x, y) = s + left = (x-1, y) + right = (x+1, y) + up = (x, y+1) + down = (x, y-1) + + for neighbours in [left, right, up, down]: + if neighbours not in blocks: + if valid(neighbours) and neighbours not in visited: + # print("neighbour", neighbours) + visited.add(neighbours) + back_pointer[neighbours] = -1 + g_function[neighbours] = float('inf') + + if valid(neighbours) and g_function[neighbours] > g_function[s] + 1: + g_function[neighbours] = g_function[s] + 1 + back_pointer[neighbours] = s + if neighbours not in close_list_anchor: + open_list[0].put(neighbours, key(neighbours, 0, goal, g_function)) + if neighbours not in close_list_inad: + for var in range(1,n_hueristic): + if key(neighbours, var, goal, g_function) <= W2 * key(neighbours, 0, goal, g_function): + # print("why not plssssssssss") + open_list[j].put(neighbours, key(neighbours, var, goal, g_function)) + + + # print + +def make_common_ground(): + some_list = [] + # block 1 + for x in range(1, 5): + for y in range(1, 6): + some_list.append((x, y)) + + # line + for x in range(15, 20): + some_list.append((x, 17)) + + # block 2 big + for x in range(10, 19): + for y in range(1, 15): + some_list.append((x, y)) + + # L block + for x in range(1, 4): + for y in range(12, 19): + some_list.append((x, y)) + for x in range(3, 13): + for y in range(16, 19): + some_list.append((x, y)) + return some_list + +hueristics = {0: consistent_hueristic, 1: hueristic_1, 2: hueristic_2} + +blocks_blk = [(0, 1),(1, 1),(2, 1),(3, 1),(4, 1),(5, 1),(6, 1),(7, 1),(8, 1),(9, 1),(10, 1),(11, 1),(12, 1),(13, 1),(14, 1),(15, 1),(16, 1),(17, 1),(18, 1), (19, 1)] +blocks_no = [] +blocks_all = make_common_ground() + + + + +blocks = blocks_blk +# hyper parameters +W1 = 1 +W2 = 1 +n = 20 +n_hueristic = 3 # one consistent and two other inconsistent + +# start and end destination +start = (0, 0) +goal = (n-1, n-1) + +t = 1 +def multi_a_star(start, goal, n_hueristic): + g_function = {start: 0, goal: float('inf')} + back_pointer = {start:-1, goal:-1} + open_list = [] + visited = set() + + for i in range(n_hueristic): + open_list.append(PriorityQueue()) + open_list[i].put(start, key(start, i, goal, g_function)) + + close_list_anchor = [] + close_list_inad = [] + while open_list[0].minkey() < float('inf'): + for i in range(1, n_hueristic): + # print("i", i) + # print(open_list[0].minkey(), open_list[i].minkey()) + if open_list[i].minkey() <= W2 * open_list[0].minkey(): + global t + t += 1 + # print("less prio") + if g_function[goal] <= open_list[i].minkey(): + if g_function[goal] < float('inf'): + do_something(back_pointer, goal, start) + else: + _, get_s = open_list[i].top_show() + visited.add(get_s) + expand_state(get_s, i, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer) + close_list_inad.append(get_s) + else: + # print("more prio") + if g_function[goal] <= open_list[0].minkey(): + if g_function[goal] < float('inf'): + do_something(back_pointer, goal, start) + else: + # print("hoolla") + get_s = open_list[0].top_show() + visited.add(get_s) + expand_state(get_s, 0, visited, g_function, close_list_anchor, close_list_inad, open_list, back_pointer) + close_list_anchor.append(get_s) + print("No path found to goal") + print() + for i in range(n-1,-1, -1): + for j in range(n): + if (j, i) in blocks: + print('#', end=' ') + elif (j, i) in back_pointer: + if (j, i) == (n-1, n-1): + print('*', end=' ') + else: + print('-', end=' ') + else: + print('*', end=' ') + if (j, i) == (n-1, n-1): + print('<-- End position', end=' ') + print() + print("^") + print("Start position") + print() + print("# is an obstacle") + print("- is the path taken by algorithm") +multi_a_star(start, goal, n_hueristic) diff --git a/graphs/a_star.py b/graphs/a_star.py new file mode 100644 index 000000000..584222e6f --- /dev/null +++ b/graphs/a_star.py @@ -0,0 +1,102 @@ +from __future__ import print_function + +grid = [[0, 1, 0, 0, 0, 0], + [0, 1, 0, 0, 0, 0],#0 are free path whereas 1's are obstacles + [0, 1, 0, 0, 0, 0], + [0, 1, 0, 0, 1, 0], + [0, 0, 0, 0, 1, 0]] + +''' +heuristic = [[9, 8, 7, 6, 5, 4], + [8, 7, 6, 5, 4, 3], + [7, 6, 5, 4, 3, 2], + [6, 5, 4, 3, 2, 1], + [5, 4, 3, 2, 1, 0]]''' + +init = [0, 0] +goal = [len(grid)-1, len(grid[0])-1] #all coordinates are given in format [y,x] +cost = 1 + +#the cost map which pushes the path closer to the goal +heuristic = [[0 for row in range(len(grid[0]))] for col in range(len(grid))] +for i in range(len(grid)): + for j in range(len(grid[0])): + heuristic[i][j] = abs(i - goal[0]) + abs(j - goal[1]) + if grid[i][j] == 1: + heuristic[i][j] = 99 #added extra penalty in the heuristic map + + +#the actions we can take +delta = [[-1, 0 ], # go up + [ 0, -1], # go left + [ 1, 0 ], # go down + [ 0, 1 ]] # go right + + +#function to search the path +def search(grid,init,goal,cost,heuristic): + + closed = [[0 for col in range(len(grid[0]))] for row in range(len(grid))]# the referrence grid + closed[init[0]][init[1]] = 1 + action = [[0 for col in range(len(grid[0]))] for row in range(len(grid))]#the action grid + + x = init[0] + y = init[1] + g = 0 + f = g + heuristic[init[0]][init[0]] + cell = [[f, g, x, y]] + + found = False # flag that is set when search is complete + resign = False # flag set if we can't find expand + + while not found and not resign: + if len(cell) == 0: + resign = True + return "FAIL" + else: + cell.sort()#to choose the least costliest action so as to move closer to the goal + cell.reverse() + next = cell.pop() + x = next[2] + y = next[3] + g = next[1] + f = next[0] + + + if x == goal[0] and y == goal[1]: + found = True + else: + for i in range(len(delta)):#to try out different valid actions + x2 = x + delta[i][0] + y2 = y + delta[i][1] + if x2 >= 0 and x2 < len(grid) and y2 >=0 and y2 < len(grid[0]): + if closed[x2][y2] == 0 and grid[x2][y2] == 0: + g2 = g + cost + f2 = g2 + heuristic[x2][y2] + cell.append([f2, g2, x2, y2]) + closed[x2][y2] = 1 + action[x2][y2] = i + invpath = [] + x = goal[0] + y = goal[1] + invpath.append([x, y])#we get the reverse path from here + while x != init[0] or y != init[1]: + x2 = x - delta[action[x][y]][0] + y2 = y - delta[action[x][y]][1] + x = x2 + y = y2 + invpath.append([x, y]) + + path = [] + for i in range(len(invpath)): + path.append(invpath[len(invpath) - 1 - i]) + print("ACTION MAP") + for i in range(len(action)): + print(action[i]) + + return path + +a = search(grid,init,goal,cost,heuristic) +for i in range(len(a)): + print(a[i]) + diff --git a/graphs/basic-graphs.py b/graphs/basic-graphs.py new file mode 100644 index 000000000..c9a269f1a --- /dev/null +++ b/graphs/basic-graphs.py @@ -0,0 +1,281 @@ +from __future__ import print_function + +try: + raw_input # Python 2 +except NameError: + raw_input = input # Python 3 + +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + +# Accept No. of Nodes and edges +n, m = map(int, raw_input().split(" ")) + +# Initialising Dictionary of edges +g = {} +for i in xrange(n): + g[i + 1] = [] + +""" +-------------------------------------------------------------------------------- + Accepting edges of Unweighted Directed Graphs +-------------------------------------------------------------------------------- +""" +for _ in xrange(m): + x, y = map(int, raw_input().split(" ")) + g[x].append(y) + +""" +-------------------------------------------------------------------------------- + Accepting edges of Unweighted Undirected Graphs +-------------------------------------------------------------------------------- +""" +for _ in xrange(m): + x, y = map(int, raw_input().split(" ")) + g[x].append(y) + g[y].append(x) + +""" +-------------------------------------------------------------------------------- + Accepting edges of Weighted Undirected Graphs +-------------------------------------------------------------------------------- +""" +for _ in xrange(m): + x, y, r = map(int, raw_input().split(" ")) + g[x].append([y, r]) + g[y].append([x, r]) + +""" +-------------------------------------------------------------------------------- + Depth First Search. + Args : G - Dictionary of edges + s - Starting Node + Vars : vis - Set of visited nodes + S - Traversal Stack +-------------------------------------------------------------------------------- +""" + + +def dfs(G, s): + vis, S = set([s]), [s] + print(s) + while S: + flag = 0 + for i in G[S[-1]]: + if i not in vis: + S.append(i) + vis.add(i) + flag = 1 + print(i) + break + if not flag: + S.pop() + + +""" +-------------------------------------------------------------------------------- + Breadth First Search. + Args : G - Dictionary of edges + s - Starting Node + Vars : vis - Set of visited nodes + Q - Traveral Stack +-------------------------------------------------------------------------------- +""" +from collections import deque + + +def bfs(G, s): + vis, Q = set([s]), deque([s]) + print(s) + while Q: + u = Q.popleft() + for v in G[u]: + if v not in vis: + vis.add(v) + Q.append(v) + print(v) + + +""" +-------------------------------------------------------------------------------- + Dijkstra's shortest path Algorithm + Args : G - Dictionary of edges + s - Starting Node + Vars : dist - Dictionary storing shortest distance from s to every other node + known - Set of knows nodes + path - Preceding node in path +-------------------------------------------------------------------------------- +""" + + +def dijk(G, s): + dist, known, path = {s: 0}, set(), {s: 0} + while True: + if len(known) == len(G) - 1: + break + mini = 100000 + for i in dist: + if i not in known and dist[i] < mini: + mini = dist[i] + u = i + known.add(u) + for v in G[u]: + if v[0] not in known: + if dist[u] + v[1] < dist.get(v[0], 100000): + dist[v[0]] = dist[u] + v[1] + path[v[0]] = u + for i in dist: + if i != s: + print(dist[i]) + + +""" +-------------------------------------------------------------------------------- + Topological Sort +-------------------------------------------------------------------------------- +""" +from collections import deque + + +def topo(G, ind=None, Q=[1]): + if ind is None: + ind = [0] * (len(G) + 1) # SInce oth Index is ignored + for u in G: + for v in G[u]: + ind[v] += 1 + Q = deque() + for i in G: + if ind[i] == 0: + Q.append(i) + if len(Q) == 0: + return + v = Q.popleft() + print(v) + for w in G[v]: + ind[w] -= 1 + if ind[w] == 0: + Q.append(w) + topo(G, ind, Q) + + +""" +-------------------------------------------------------------------------------- + Reading an Adjacency matrix +-------------------------------------------------------------------------------- +""" + + +def adjm(): + n, a = raw_input(), [] + for i in xrange(n): + a.append(map(int, raw_input().split())) + return a, n + + +""" +-------------------------------------------------------------------------------- + Floyd Warshall's algorithm + Args : G - Dictionary of edges + s - Starting Node + Vars : dist - Dictionary storing shortest distance from s to every other node + known - Set of knows nodes + path - Preceding node in path + +-------------------------------------------------------------------------------- +""" + + +def floy(A_and_n): + (A, n) = A_and_n + dist = list(A) + path = [[0] * n for i in xrange(n)] + for k in xrange(n): + for i in xrange(n): + for j in xrange(n): + if dist[i][j] > dist[i][k] + dist[k][j]: + dist[i][j] = dist[i][k] + dist[k][j] + path[i][k] = k + print(dist) + + +""" +-------------------------------------------------------------------------------- + Prim's MST Algorithm + Args : G - Dictionary of edges + s - Starting Node + Vars : dist - Dictionary storing shortest distance from s to nearest node + known - Set of knows nodes + path - Preceding node in path +-------------------------------------------------------------------------------- +""" + + +def prim(G, s): + dist, known, path = {s: 0}, set(), {s: 0} + while True: + if len(known) == len(G) - 1: + break + mini = 100000 + for i in dist: + if i not in known and dist[i] < mini: + mini = dist[i] + u = i + known.add(u) + for v in G[u]: + if v[0] not in known: + if v[1] < dist.get(v[0], 100000): + dist[v[0]] = v[1] + path[v[0]] = u + + +""" +-------------------------------------------------------------------------------- + Accepting Edge list + Vars : n - Number of nodes + m - Number of edges + Returns : l - Edge list + n - Number of Nodes +-------------------------------------------------------------------------------- +""" + + +def edglist(): + n, m = map(int, raw_input().split(" ")) + l = [] + for i in xrange(m): + l.append(map(int, raw_input().split(' '))) + return l, n + + +""" +-------------------------------------------------------------------------------- + Kruskal's MST Algorithm + Args : E - Edge list + n - Number of Nodes + Vars : s - Set of all nodes as unique disjoint sets (initially) +-------------------------------------------------------------------------------- +""" + + +def krusk(E_and_n): + # Sort edges on the basis of distance + (E, n) = E_and_n + E.sort(reverse=True, key=lambda x: x[2]) + s = [set([i]) for i in range(1, n + 1)] + while True: + if len(s) == 1: + break + print(s) + x = E.pop() + for i in xrange(len(s)): + if x[0] in s[i]: + break + for j in xrange(len(s)): + if x[1] in s[j]: + if i == j: + break + s[j].update(s[i]) + s.pop(i) + break diff --git a/graphs/minimum_spanning_tree_kruskal.py b/graphs/minimum_spanning_tree_kruskal.py new file mode 100644 index 000000000..930aab225 --- /dev/null +++ b/graphs/minimum_spanning_tree_kruskal.py @@ -0,0 +1,32 @@ +from __future__ import print_function +num_nodes, num_edges = list(map(int,raw_input().split())) + +edges = [] + +for i in range(num_edges): + node1, node2, cost = list(map(int,raw_input().split())) + edges.append((i,node1,node2,cost)) + +edges = sorted(edges, key=lambda edge: edge[3]) + +parent = [i for i in range(num_nodes)] + +def find_parent(i): + if(i != parent[i]): + parent[i] = find_parent(parent[i]) + return parent[i] + +minimum_spanning_tree_cost = 0 +minimum_spanning_tree = [] + +for edge in edges: + parent_a = find_parent(edge[1]) + parent_b = find_parent(edge[2]) + if(parent_a != parent_b): + minimum_spanning_tree_cost += edge[3] + minimum_spanning_tree.append(edge) + parent[parent_a] = parent_b + +print(minimum_spanning_tree_cost) +for edge in minimum_spanning_tree: + print(edge) diff --git a/graphs/scc_kosaraju.py b/graphs/scc_kosaraju.py new file mode 100644 index 000000000..90d3568fa --- /dev/null +++ b/graphs/scc_kosaraju.py @@ -0,0 +1,46 @@ +from __future__ import print_function +# n - no of nodes, m - no of edges +n, m = list(map(int,raw_input().split())) + +g = [[] for i in range(n)] #graph +r = [[] for i in range(n)] #reversed graph +# input graph data (edges) +for i in range(m): + u, v = list(map(int,raw_input().split())) + g[u].append(v) + r[v].append(u) + +stack = [] +visit = [False]*n +scc = [] +component = [] + +def dfs(u): + global g, r, scc, component, visit, stack + if visit[u]: return + visit[u] = True + for v in g[u]: + dfs(v) + stack.append(u) + +def dfs2(u): + global g, r, scc, component, visit, stack + if visit[u]: return + visit[u] = True + component.append(u) + for v in r[u]: + dfs2(v) + +def kosaraju(): + global g, r, scc, component, visit, stack + for i in range(n): + dfs(i) + visit = [False]*n + for i in stack[::-1]: + if visit[i]: continue + component = [] + dfs2(i) + scc.append(component) + return scc + +print(kosaraju()) diff --git a/graphs/tarjans_scc.py b/graphs/tarjans_scc.py new file mode 100644 index 000000000..89754e593 --- /dev/null +++ b/graphs/tarjans_scc.py @@ -0,0 +1,78 @@ +from collections import deque + + +def tarjan(g): + """ + Tarjan's algo for finding strongly connected components in a directed graph + + Uses two main attributes of each node to track reachability, the index of that node within a component(index), + and the lowest index reachable from that node(lowlink). + + We then perform a dfs of the each component making sure to update these parameters for each node and saving the + nodes we visit on the way. + + If ever we find that the lowest reachable node from a current node is equal to the index of the current node then it + must be the root of a strongly connected component and so we save it and it's equireachable vertices as a strongly + connected component. + + Complexity: strong_connect() is called at most once for each node and has a complexity of O(|E|) as it is DFS. + Therefore this has complexity O(|V| + |E|) for a graph G = (V, E) + + """ + + n = len(g) + stack = deque() + on_stack = [False for _ in range(n)] + index_of = [-1 for _ in range(n)] + lowlink_of = index_of[:] + + def strong_connect(v, index, components): + index_of[v] = index # the number when this node is seen + lowlink_of[v] = index # lowest rank node reachable from here + index += 1 + stack.append(v) + on_stack[v] = True + + for w in g[v]: + if index_of[w] == -1: + index = strong_connect(w, index, components) + lowlink_of[v] = lowlink_of[w] if lowlink_of[w] < lowlink_of[v] else lowlink_of[v] + elif on_stack[w]: + lowlink_of[v] = lowlink_of[w] if lowlink_of[w] < lowlink_of[v] else lowlink_of[v] + + if lowlink_of[v] == index_of[v]: + component = [] + w = stack.pop() + on_stack[w] = False + component.append(w) + while w != v: + w = stack.pop() + on_stack[w] = False + component.append(w) + components.append(component) + return index + + components = [] + for v in range(n): + if index_of[v] == -1: + strong_connect(v, 0, components) + + return components + + +def create_graph(n, edges): + g = [[] for _ in range(n)] + for u, v in edges: + g[u].append(v) + return g + + +if __name__ == '__main__': + # Test + n_vertices = 7 + source = [0, 0, 1, 2, 3, 3, 4, 4, 6] + target = [1, 3, 2, 0, 1, 4, 5, 6, 5] + edges = [(u, v) for u, v in zip(source, target)] + g = create_graph(n_vertices, edges) + + assert [[5], [6], [4], [3, 2, 1, 0]] == tarjan(g) diff --git a/linear_algebra_python/README.md b/linear_algebra_python/README.md new file mode 100644 index 000000000..ebfcdab7b --- /dev/null +++ b/linear_algebra_python/README.md @@ -0,0 +1,74 @@ +# Linear algebra library for Python + +This module contains some useful classes and functions for dealing with linear algebra in python 2. + +--- + +## Overview + +- class Vector + - This class represents a vector of arbitray size and operations on it. + + **Overview about the methods:** + + - constructor(components : list) : init the vector + - set(components : list) : changes the vector components. + - __str__() : toString method + - component(i : int): gets the i-th component (start by 0) + - size() : gets the size of the vector (number of components) + - euclidLength() : returns the eulidean length of the vector. + - operator + : vector addition + - operator - : vector subtraction + - operator * : scalar multiplication and dot product + - copy() : copies this vector and returns it. + - changeComponent(pos,value) : changes the specified component. + +- function zeroVector(dimension) + - returns a zero vector of 'dimension' +- function unitBasisVector(dimension,pos) + - returns a unit basis vector with a One at index 'pos' (indexing at 0) +- function axpy(scalar,vector1,vector2) + - computes the axpy operation +- function randomVector(N,a,b) + - returns a random vector of size N, with random integer components between 'a' and 'b'. +- class Matrix + - This class represents a matrix of arbitrary size and operations on it. + + **Overview about the methods:** + + - __str__() : returns a string representation + - operator * : implements the matrix vector multiplication + implements the matrix-scalar multiplication. + - changeComponent(x,y,value) : changes the specified component. + - component(x,y) : returns the specified component. + - width() : returns the width of the matrix + - height() : returns the height of the matrix + - operator + : implements the matrix-addition. + - operator - _ implements the matrix-subtraction +- function squareZeroMatrix(N) + - returns a square zero-matrix of dimension NxN +- function randomMatrix(W,H,a,b) + - returns a random matrix WxH with integer components between 'a' and 'b' +--- + +## Documentation + +The module is well documented. You can use the python in-built ```help(...)``` function. +For instance: ```help(Vector)``` gives you all information about the Vector-class. +Or ```help(unitBasisVector)``` gives you all information you needed about the +global function ```unitBasisVector(...)```. If you need informations about a certain +method you type ```help(CLASSNAME.METHODNAME)```. + +--- + +## Usage + +You will find the module in the **src** directory its called ```lib.py```. You need to +import this module in your project. Alternative you can also use the file ```lib.pyc``` in python-bytecode. + +--- + +## Tests + +In the **src** directory you also find the test-suite, its called ```tests.py```. +The test-suite uses the built-in python-test-framework **unittest**. diff --git a/linear_algebra_python/src/lib.py b/linear_algebra_python/src/lib.py new file mode 100644 index 000000000..66f27ff89 --- /dev/null +++ b/linear_algebra_python/src/lib.py @@ -0,0 +1,364 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Feb 26 14:29:11 2018 + +@author: Christian Bender +@license: MIT-license + +This module contains some useful classes and functions for dealing +with linear algebra in python. + +Overview: + +- class Vector +- function zeroVector(dimension) +- function unitBasisVector(dimension,pos) +- function axpy(scalar,vector1,vector2) +- function randomVector(N,a,b) +- class Matrix +- function squareZeroMatrix(N) +- function randomMatrix(W,H,a,b) +""" + + +import math +import random + + +class Vector(object): + """ + This class represents a vector of arbitray size. + You need to give the vector components. + + Overview about the methods: + + constructor(components : list) : init the vector + set(components : list) : changes the vector components. + __str__() : toString method + component(i : int): gets the i-th component (start by 0) + size() : gets the size of the vector (number of components) + euclidLength() : returns the eulidean length of the vector. + operator + : vector addition + operator - : vector subtraction + operator * : scalar multiplication and dot product + copy() : copies this vector and returns it. + changeComponent(pos,value) : changes the specified component. + TODO: compare-operator + """ + def __init__(self,components): + """ + input: components or nothing + simple constructor for init the vector + """ + self.__components = components + def set(self,components): + """ + input: new components + changes the components of the vector. + replace the components with newer one. + """ + if len(components) > 0: + self.__components = components + else: + raise Exception("please give any vector") + def __str__(self): + """ + returns a string representation of the vector + """ + ans = "(" + length = len(self.__components) + for i in range(length): + if i != length-1: + ans += str(self.__components[i]) + "," + else: + ans += str(self.__components[i]) + ")" + if len(ans) == 1: + ans += ")" + return ans + def component(self,i): + """ + input: index (start at 0) + output: the i-th component of the vector. + """ + if i < len(self.__components) and i >= 0: + return self.__components[i] + else: + raise Exception("index out of range") + def size(self): + """ + returns the size of the vector + """ + return len(self.__components) + def eulidLength(self): + """ + returns the eulidean length of the vector + """ + summe = 0 + for c in self.__components: + summe += c**2 + return math.sqrt(summe) + def __add__(self,other): + """ + input: other vector + assumes: other vector has the same size + returns a new vector that represents the sum. + """ + size = self.size() + result = [] + if size == other.size(): + for i in range(size): + result.append(self.__components[i] + other.component(i)) + else: + raise Exception("must have the same size") + return Vector(result) + def __sub__(self,other): + """ + input: other vector + assumes: other vector has the same size + returns a new vector that represents the differenz. + """ + size = self.size() + result = [] + if size == other.size(): + for i in range(size): + result.append(self.__components[i] - other.component(i)) + else: # error case + raise Exception("must have the same size") + return Vector(result) + def __mul__(self,other): + """ + mul implements the scalar multiplication + and the dot-product + """ + ans = [] + if isinstance(other,float) or isinstance(other,int): + for c in self.__components: + ans.append(c*other) + elif (isinstance(other,Vector) and (self.size() == other.size())): + size = self.size() + summe = 0 + for i in range(size): + summe += self.__components[i] * other.component(i) + return summe + else: # error case + raise Exception("invalide operand!") + return Vector(ans) + def copy(self): + """ + copies this vector and returns it. + """ + components = [x for x in self.__components] + return Vector(components) + def changeComponent(self,pos,value): + """ + input: an index (pos) and a value + changes the specified component (pos) with the + 'value' + """ + #precondition + assert (pos >= 0 and pos < len(self.__components)) + self.__components[pos] = value + +def zeroVector(dimension): + """ + returns a zero-vector of size 'dimension' + """ + #precondition + assert(isinstance(dimension,int)) + ans = [] + for i in range(dimension): + ans.append(0) + return Vector(ans) + + +def unitBasisVector(dimension,pos): + """ + returns a unit basis vector with a One + at index 'pos' (indexing at 0) + """ + #precondition + assert(isinstance(dimension,int) and (isinstance(pos,int))) + ans = [] + for i in range(dimension): + if i != pos: + ans.append(0) + else: + ans.append(1) + return Vector(ans) + + +def axpy(scalar,x,y): + """ + input: a 'scalar' and two vectors 'x' and 'y' + output: a vector + computes the axpy operation + """ + # precondition + assert(isinstance(x,Vector) and (isinstance(y,Vector)) \ + and (isinstance(scalar,int) or isinstance(scalar,float))) + return (x*scalar + y) + + +def randomVector(N,a,b): + """ + input: size (N) of the vector. + random range (a,b) + output: returns a random vector of size N, with + random integer components between 'a' and 'b'. + """ + ans = zeroVector(N) + random.seed(None) + for i in range(N): + ans.changeComponent(i,random.randint(a,b)) + return ans + + +class Matrix(object): + """ + class: Matrix + This class represents a arbitrary matrix. + + Overview about the methods: + + __str__() : returns a string representation + operator * : implements the matrix vector multiplication + implements the matrix-scalar multiplication. + changeComponent(x,y,value) : changes the specified component. + component(x,y) : returns the specified component. + width() : returns the width of the matrix + height() : returns the height of the matrix + operator + : implements the matrix-addition. + operator - _ implements the matrix-subtraction + """ + def __init__(self,matrix,w,h): + """ + simple constructor for initialzes + the matrix with components. + """ + self.__matrix = matrix + self.__width = w + self.__height = h + def __str__(self): + """ + returns a string representation of this + matrix. + """ + ans = "" + for i in range(self.__height): + ans += "|" + for j in range(self.__width): + if j < self.__width -1: + ans += str(self.__matrix[i][j]) + "," + else: + ans += str(self.__matrix[i][j]) + "|\n" + return ans + def changeComponent(self,x,y, value): + """ + changes the x-y component of this matrix + """ + if x >= 0 and x < self.__height and y >= 0 and y < self.__width: + self.__matrix[x][y] = value + else: + raise Exception ("changeComponent: indices out of bounds") + def component(self,x,y): + """ + returns the specified (x,y) component + """ + if x >= 0 and x < self.__height and y >= 0 and y < self.__width: + return self.__matrix[x][y] + else: + raise Exception ("changeComponent: indices out of bounds") + def width(self): + """ + getter for the width + """ + return self.__width + def height(self): + """ + getter for the height + """ + return self.__height + def __mul__(self,other): + """ + implements the matrix-vector multiplication. + implements the matrix-scalar multiplication + """ + if isinstance(other, Vector): # vector-matrix + if (other.size() == self.__width): + ans = zeroVector(self.__height) + for i in range(self.__height): + summe = 0 + for j in range(self.__width): + summe += other.component(j) * self.__matrix[i][j] + ans.changeComponent(i,summe) + summe = 0 + return ans + else: + raise Exception("vector must have the same size as the " + + "number of columns of the matrix!") + elif isinstance(other,int) or isinstance(other,float): # matrix-scalar + matrix = [] + for i in range(self.__height): + row = [] + for j in range(self.__width): + row.append(self.__matrix[i][j] * other) + matrix.append(row) + return Matrix(matrix,self.__width,self.__height) + def __add__(self,other): + """ + implements the matrix-addition. + """ + if (self.__width == other.width() and self.__height == other.height()): + matrix = [] + for i in range(self.__height): + row = [] + for j in range(self.__width): + row.append(self.__matrix[i][j] + other.component(i,j)) + matrix.append(row) + return Matrix(matrix,self.__width,self.__height) + else: + raise Exception("matrix must have the same dimension!") + def __sub__(self,other): + """ + implements the matrix-subtraction. + """ + if (self.__width == other.width() and self.__height == other.height()): + matrix = [] + for i in range(self.__height): + row = [] + for j in range(self.__width): + row.append(self.__matrix[i][j] - other.component(i,j)) + matrix.append(row) + return Matrix(matrix,self.__width,self.__height) + else: + raise Exception("matrix must have the same dimension!") + + +def squareZeroMatrix(N): + """ + returns a square zero-matrix of dimension NxN + """ + ans = [] + for i in range(N): + row = [] + for j in range(N): + row.append(0) + ans.append(row) + return Matrix(ans,N,N) + + +def randomMatrix(W,H,a,b): + """ + returns a random matrix WxH with integer components + between 'a' and 'b' + """ + matrix = [] + random.seed(None) + for i in range(H): + row = [] + for j in range(W): + row.append(random.randint(a,b)) + matrix.append(row) + return Matrix(matrix,W,H) + + \ No newline at end of file diff --git a/linear_algebra_python/src/tests.py b/linear_algebra_python/src/tests.py new file mode 100644 index 000000000..b84612b4c --- /dev/null +++ b/linear_algebra_python/src/tests.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Feb 26 15:40:07 2018 + +@author: Christian Bender +@license: MIT-license + +This file contains the test-suite for the linear algebra library. +""" + +import unittest +from lib import * + +class Test(unittest.TestCase): + def test_component(self): + """ + test for method component + """ + x = Vector([1,2,3]) + self.assertEqual(x.component(0),1) + self.assertEqual(x.component(2),3) + try: + y = Vector() + self.assertTrue(False) + except: + self.assertTrue(True) + def test_str(self): + """ + test for toString() method + """ + x = Vector([0,0,0,0,0,1]) + self.assertEqual(x.__str__(),"(0,0,0,0,0,1)") + def test_size(self): + """ + test for size()-method + """ + x = Vector([1,2,3,4]) + self.assertEqual(x.size(),4) + def test_euclidLength(self): + """ + test for the eulidean length + """ + x = Vector([1,2]) + self.assertAlmostEqual(x.eulidLength(),2.236,3) + def test_add(self): + """ + test for + operator + """ + x = Vector([1,2,3]) + y = Vector([1,1,1]) + self.assertEqual((x+y).component(0),2) + self.assertEqual((x+y).component(1),3) + self.assertEqual((x+y).component(2),4) + def test_sub(self): + """ + test for - operator + """ + x = Vector([1,2,3]) + y = Vector([1,1,1]) + self.assertEqual((x-y).component(0),0) + self.assertEqual((x-y).component(1),1) + self.assertEqual((x-y).component(2),2) + def test_mul(self): + """ + test for * operator + """ + x = Vector([1,2,3]) + a = Vector([2,-1,4]) # for test of dot-product + b = Vector([1,-2,-1]) + self.assertEqual((x*3.0).__str__(),"(3.0,6.0,9.0)") + self.assertEqual((a*b),0) + def test_zeroVector(self): + """ + test for the global function zeroVector(...) + """ + self.assertTrue(zeroVector(10).__str__().count("0") == 10) + def test_unitBasisVector(self): + """ + test for the global function unitBasisVector(...) + """ + self.assertEqual(unitBasisVector(3,1).__str__(),"(0,1,0)") + def test_axpy(self): + """ + test for the global function axpy(...) (operation) + """ + x = Vector([1,2,3]) + y = Vector([1,0,1]) + self.assertEqual(axpy(2,x,y).__str__(),"(3,4,7)") + def test_copy(self): + """ + test for the copy()-method + """ + x = Vector([1,0,0,0,0,0]) + y = x.copy() + self.assertEqual(x.__str__(),y.__str__()) + def test_changeComponent(self): + """ + test for the changeComponent(...)-method + """ + x = Vector([1,0,0]) + x.changeComponent(0,0) + x.changeComponent(1,1) + self.assertEqual(x.__str__(),"(0,1,0)") + def test_str_matrix(self): + A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3) + self.assertEqual("|1,2,3|\n|2,4,5|\n|6,7,8|\n",A.__str__()) + def test__mul__matrix(self): + A = Matrix([[1,2,3],[4,5,6],[7,8,9]],3,3) + x = Vector([1,2,3]) + self.assertEqual("(14,32,50)",(A*x).__str__()) + self.assertEqual("|2,4,6|\n|8,10,12|\n|14,16,18|\n",(A*2).__str__()) + def test_changeComponent_matrix(self): + A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3) + A.changeComponent(0,2,5) + self.assertEqual("|1,2,5|\n|2,4,5|\n|6,7,8|\n",A.__str__()) + def test_component_matrix(self): + A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3) + self.assertEqual(7,A.component(2,1),0.01) + def test__add__matrix(self): + A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3) + B = Matrix([[1,2,7],[2,4,5],[6,7,10]],3,3) + self.assertEqual("|2,4,10|\n|4,8,10|\n|12,14,18|\n",(A+B).__str__()) + def test__sub__matrix(self): + A = Matrix([[1,2,3],[2,4,5],[6,7,8]],3,3) + B = Matrix([[1,2,7],[2,4,5],[6,7,10]],3,3) + self.assertEqual("|0,0,-4|\n|0,0,0|\n|0,0,-2|\n",(A-B).__str__()) + def test_squareZeroMatrix(self): + self.assertEqual('|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|' + +'\n|0,0,0,0,0|\n',squareZeroMatrix(5).__str__()) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/maths/BasicMaths.py b/maths/BasicMaths.py new file mode 100644 index 000000000..6e8c919a0 --- /dev/null +++ b/maths/BasicMaths.py @@ -0,0 +1,74 @@ +import math + +def primeFactors(n): + pf = [] + while n % 2 == 0: + pf.append(2) + n = int(n / 2) + + for i in range(3, int(math.sqrt(n))+1, 2): + while n % i == 0: + pf.append(i) + n = int(n / i) + + if n > 2: + pf.append(n) + + return pf + +def numberOfDivisors(n): + div = 1 + + temp = 1 + while n % 2 == 0: + temp += 1 + n = int(n / 2) + div = div * (temp) + + for i in range(3, int(math.sqrt(n))+1, 2): + temp = 1 + while n % i == 0: + temp += 1 + n = int(n / i) + div = div * (temp) + + return div + +def sumOfDivisors(n): + s = 1 + + temp = 1 + while n % 2 == 0: + temp += 1 + n = int(n / 2) + if temp > 1: + s *= (2**temp - 1) / (2 - 1) + + for i in range(3, int(math.sqrt(n))+1, 2): + temp = 1 + while n % i == 0: + temp += 1 + n = int(n / i) + if temp > 1: + s *= (i**temp - 1) / (i - 1) + + return s + +def eulerPhi(n): + l = primeFactors(n) + l = set(l) + s = n + for x in l: + s *= (x - 1)/x + return s + +def main(): + print(primeFactors(100)) + print(numberOfDivisors(100)) + print(sumOfDivisors(100)) + print(eulerPhi(100)) + +if __name__ == '__main__': + main() + + \ No newline at end of file diff --git a/maths/FibonacciSequenceRecursion.py b/maths/FibonacciSequenceRecursion.py new file mode 100644 index 000000000..b0b10fd07 --- /dev/null +++ b/maths/FibonacciSequenceRecursion.py @@ -0,0 +1,18 @@ +# Fibonacci Sequence Using Recursion + +def recur_fibo(n): + return n if n <= 1 else (recur_fibo(n-1) + recur_fibo(n-2)) + +def isPositiveInteger(limit): + return limit >= 0 + +def main(): + limit = int(input("How many terms to include in fibonacci series: ")) + if isPositiveInteger(limit): + print("The first {limit} terms of the fibonacci series are as follows:") + print([recur_fibo(n) for n in range(limit)]) + else: + print("Please enter a positive integer: ") + +if __name__ == '__main__': + main() diff --git a/maths/GreaterCommonDivisor.py b/maths/GreaterCommonDivisor.py new file mode 100644 index 000000000..15adaca1f --- /dev/null +++ b/maths/GreaterCommonDivisor.py @@ -0,0 +1,15 @@ +# Greater Common Divisor - https://en.wikipedia.org/wiki/Greatest_common_divisor +def gcd(a, b): + return b if a == 0 else gcd(b % a, a) + +def main(): + try: + nums = input("Enter two Integers separated by comma (,): ").split(',') + num1 = int(nums[0]); num2 = int(nums[1]) + except (IndexError, UnboundLocalError, ValueError): + print("Wrong Input") + print(f"gcd({num1}, {num2}) = {gcd(num1, num2)}") + +if __name__ == '__main__': + main() + diff --git a/maths/ModularExponential.py b/maths/ModularExponential.py new file mode 100644 index 000000000..b3f4c00bd --- /dev/null +++ b/maths/ModularExponential.py @@ -0,0 +1,20 @@ +def modularExponential(base, power, mod): + if power < 0: + return -1 + base %= mod + result = 1 + + while power > 0: + if power & 1: + result = (result * base) % mod + power = power >> 1 + base = (base * base) % mod + return result + + +def main(): + print(modularExponential(3, 200, 13)) + + +if __name__ == '__main__': + main() diff --git a/maths/SegmentedSieve.py b/maths/SegmentedSieve.py new file mode 100644 index 000000000..52ca6fbe6 --- /dev/null +++ b/maths/SegmentedSieve.py @@ -0,0 +1,46 @@ +import math + +def sieve(n): + in_prime = [] + start = 2 + end = int(math.sqrt(n)) # Size of every segment + temp = [True] * (end + 1) + prime = [] + + while(start <= end): + if temp[start] == True: + in_prime.append(start) + for i in range(start*start, end+1, start): + if temp[i] == True: + temp[i] = False + start += 1 + prime += in_prime + + low = end + 1 + high = low + end - 1 + if high > n: + high = n + + while(low <= n): + temp = [True] * (high-low+1) + for each in in_prime: + + t = math.floor(low / each) * each + if t < low: + t += each + + for j in range(t, high+1, each): + temp[j - low] = False + + for j in range(len(temp)): + if temp[j] == True: + prime.append(j+low) + + low = high + 1 + high = low + end - 1 + if high > n: + high = n + + return prime + +print(sieve(10**6)) \ No newline at end of file diff --git a/maths/SieveOfEratosthenes.py b/maths/SieveOfEratosthenes.py new file mode 100644 index 000000000..2b132405a --- /dev/null +++ b/maths/SieveOfEratosthenes.py @@ -0,0 +1,24 @@ +import math +n = int(raw_input("Enter n: ")) + +def sieve(n): + l = [True] * (n+1) + prime = [] + start = 2 + end = int(math.sqrt(n)) + while(start <= end): + if l[start] == True: + prime.append(start) + for i in range(start*start, n+1, start): + if l[i] == True: + l[i] = False + start += 1 + + for j in range(end+1,n+1): + if l[j] == True: + prime.append(j) + + return prime + +print(sieve(n)) + \ No newline at end of file diff --git a/maths/SimpsonRule.py b/maths/SimpsonRule.py new file mode 100644 index 000000000..091c86c17 --- /dev/null +++ b/maths/SimpsonRule.py @@ -0,0 +1,49 @@ + +''' +Numerical integration or quadrature for a smooth function f with known values at x_i + +This method is the classical approch of suming 'Equally Spaced Abscissas' + +method 2: +"Simpson Rule" + +''' +from __future__ import print_function + + +def method_2(boundary, steps): +# "Simpson Rule" +# int(f) = delta_x/2 * (b-a)/3*(f1 + 4f2 + 2f_3 + ... + fn) + h = (boundary[1] - boundary[0]) / steps + a = boundary[0] + b = boundary[1] + x_i = makePoints(a,b,h) + y = 0.0 + y += (h/3.0)*f(a) + cnt = 2 + for i in x_i: + y += (h/3)*(4-2*(cnt%2))*f(i) + cnt += 1 + y += (h/3.0)*f(b) + return y + +def makePoints(a,b,h): + x = a + h + while x < (b-h): + yield x + x = x + h + +def f(x): #enter your function here + y = (x-0)*(x-0) + return y + +def main(): + a = 0.0 #Lower bound of integration + b = 1.0 #Upper bound of integration + steps = 10.0 #define number of steps or resolution + boundary = [a, b] #define boundary of integration + y = method_2(boundary, steps) + print('y = {0}'.format(y)) + +if __name__ == '__main__': + main() diff --git a/maths/TrapezoidalRule.py b/maths/TrapezoidalRule.py new file mode 100644 index 000000000..52310c1ed --- /dev/null +++ b/maths/TrapezoidalRule.py @@ -0,0 +1,46 @@ +''' +Numerical integration or quadrature for a smooth function f with known values at x_i + +This method is the classical approch of suming 'Equally Spaced Abscissas' + +method 1: +"extended trapezoidal rule" + +''' +from __future__ import print_function + +def method_1(boundary, steps): +# "extended trapezoidal rule" +# int(f) = dx/2 * (f1 + 2f2 + ... + fn) + h = (boundary[1] - boundary[0]) / steps + a = boundary[0] + b = boundary[1] + x_i = makePoints(a,b,h) + y = 0.0 + y += (h/2.0)*f(a) + for i in x_i: + #print(i) + y += h*f(i) + y += (h/2.0)*f(b) + return y + +def makePoints(a,b,h): + x = a + h + while x < (b-h): + yield x + x = x + h + +def f(x): #enter your function here + y = (x-0)*(x-0) + return y + +def main(): + a = 0.0 #Lower bound of integration + b = 1.0 #Upper bound of integration + steps = 10.0 #define number of steps or resolution + boundary = [a, b] #define boundary of integration + y = method_1(boundary, steps) + print('y = {0}'.format(y)) + +if __name__ == '__main__': + main() diff --git a/neural_network/FCN.ipynb b/neural_network/FCN.ipynb new file mode 100644 index 000000000..a8bcf4bee --- /dev/null +++ b/neural_network/FCN.ipynb @@ -0,0 +1,327 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Standard (Fully Connected) Neural Network" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "#Use in Markup cell type\n", + "#![alt text](imagename.png \"Title\") " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Implementing Fully connected Neural Net" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Loading Required packages and Data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "###1. Load Data and Splot Data\n", + "from keras.datasets import mnist\n", + "from keras.models import Sequential \n", + "from keras.layers.core import Dense, Activation\n", + "from keras.utils import np_utils\n", + "(X_train, Y_train), (X_test, Y_test) = mnist.load_data()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Preprocessing" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "n = 10 # how many digits we will display\n", + "plt.figure(figsize=(20, 4))\n", + "for i in range(n):\n", + " # display original\n", + " ax = plt.subplot(2, n, i + 1)\n", + " plt.imshow(X_test[i].reshape(28, 28))\n", + " plt.gray()\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + "plt.show()\n", + "plt.close()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Previous X_train shape: (60000, 28, 28) \n", + "Previous Y_train shape:(60000,)\n", + "New X_train shape: (60000, 784) \n", + "New Y_train shape:(60000, 10)\n" + ] + } + ], + "source": [ + "print(\"Previous X_train shape: {} \\nPrevious Y_train shape:{}\".format(X_train.shape, Y_train.shape))\n", + "X_train = X_train.reshape(60000, 784) \n", + "X_test = X_test.reshape(10000, 784)\n", + "X_train = X_train.astype('float32') \n", + "X_test = X_test.astype('float32') \n", + "X_train /= 255 \n", + "X_test /= 255\n", + "classes = 10\n", + "Y_train = np_utils.to_categorical(Y_train, classes) \n", + "Y_test = np_utils.to_categorical(Y_test, classes)\n", + "print(\"New X_train shape: {} \\nNew Y_train shape:{}\".format(X_train.shape, Y_train.shape))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Setting up parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "input_size = 784\n", + "batch_size = 200 \n", + "hidden1 = 400\n", + "hidden2 = 20\n", + "epochs = 2" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Building the FCN Model" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "dense_1 (Dense) (None, 400) 314000 \n", + "_________________________________________________________________\n", + "dense_2 (Dense) (None, 20) 8020 \n", + "_________________________________________________________________\n", + "dense_3 (Dense) (None, 10) 210 \n", + "=================================================================\n", + "Total params: 322,230\n", + "Trainable params: 322,230\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "###4.Build the model\n", + "model = Sequential() \n", + "model.add(Dense(hidden1, input_dim=input_size, activation='relu'))\n", + "# output = relu (dot (W, input) + bias)\n", + "model.add(Dense(hidden2, activation='relu'))\n", + "model.add(Dense(classes, activation='softmax')) \n", + "\n", + "# Compilation\n", + "model.compile(loss='categorical_crossentropy', \n", + " metrics=['accuracy'], optimizer='sgd')\n", + "model.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Training The Model" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/10\n", + " - 12s - loss: 1.4482 - acc: 0.6251\n", + "Epoch 2/10\n", + " - 3s - loss: 0.6239 - acc: 0.8482\n", + "Epoch 3/10\n", + " - 3s - loss: 0.4582 - acc: 0.8798\n", + "Epoch 4/10\n", + " - 3s - loss: 0.3941 - acc: 0.8936\n", + "Epoch 5/10\n", + " - 3s - loss: 0.3579 - acc: 0.9011\n", + "Epoch 6/10\n", + " - 4s - loss: 0.3328 - acc: 0.9070\n", + "Epoch 7/10\n", + " - 3s - loss: 0.3138 - acc: 0.9118\n", + "Epoch 8/10\n", + " - 3s - loss: 0.2980 - acc: 0.9157\n", + "Epoch 9/10\n", + " - 3s - loss: 0.2849 - acc: 0.9191\n", + "Epoch 10/10\n", + " - 3s - loss: 0.2733 - acc: 0.9223\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Fitting on Data\n", + "model.fit(X_train, Y_train, batch_size=batch_size, epochs=10, verbose=2)\n", + "###5.Test " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "#### Testing The Model" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10000/10000 [==============================] - 1s 121us/step\n", + "\n", + "Test accuracy: 0.9257\n", + "[0 6 9 0 1 5 9 7 3 4]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "score = model.evaluate(X_test, Y_test, verbose=1)\n", + "print('\\n''Test accuracy:', score[1])\n", + "mask = range(10,20)\n", + "X_valid = X_test[mask]\n", + "y_pred = model.predict_classes(X_valid)\n", + "print(y_pred)\n", + "plt.figure(figsize=(20, 4))\n", + "for i in range(n):\n", + " # display original\n", + " ax = plt.subplot(2, n, i + 1)\n", + " plt.imshow(X_valid[i].reshape(28, 28))\n", + " plt.gray()\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + "plt.show()\n", + "plt.close()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/neural_network/bpnn.py b/neural_network/bpnn.py new file mode 100644 index 000000000..0865e35f0 --- /dev/null +++ b/neural_network/bpnn.py @@ -0,0 +1,193 @@ +#!/usr/bin/python +# encoding=utf8 + +''' + +A Framework of Back Propagation Neural Network(BP) model + +Easy to use: + * add many layers as you want ï¼ï¼ï¼ + * clearly see how the loss decreasing +Easy to expand: + * more activation functions + * more loss functions + * more optimization method + +Author: Stephen Lee +Github : https://github.com/RiptideBo +Date: 2017.11.23 + +''' + +import numpy as np +import matplotlib.pyplot as plt + + +def sigmoid(x): + return 1 / (1 + np.exp(-1 * x)) + +class DenseLayer(): + ''' + Layers of BP neural network + ''' + def __init__(self,units,activation=None,learning_rate=None,is_input_layer=False): + ''' + common connected layer of bp network + :param units: numbers of neural units + :param activation: activation function + :param learning_rate: learning rate for paras + :param is_input_layer: whether it is input layer or not + ''' + self.units = units + self.weight = None + self.bias = None + self.activation = activation + if learning_rate is None: + learning_rate = 0.3 + self.learn_rate = learning_rate + self.is_input_layer = is_input_layer + + def initializer(self,back_units): + self.weight = np.asmatrix(np.random.normal(0,0.5,(self.units,back_units))) + self.bias = np.asmatrix(np.random.normal(0,0.5,self.units)).T + if self.activation is None: + self.activation = sigmoid + + def cal_gradient(self): + if self.activation == sigmoid: + gradient_mat = np.dot(self.output ,(1- self.output).T) + gradient_activation = np.diag(np.diag(gradient_mat)) + else: + gradient_activation = 1 + return gradient_activation + + def forward_propagation(self,xdata): + self.xdata = xdata + if self.is_input_layer: + # input layer + self.wx_plus_b = xdata + self.output = xdata + return xdata + else: + self.wx_plus_b = np.dot(self.weight,self.xdata) - self.bias + self.output = self.activation(self.wx_plus_b) + return self.output + + def back_propagation(self,gradient): + + gradient_activation = self.cal_gradient() # i * i ç»´ + gradient = np.asmatrix(np.dot(gradient.T,gradient_activation)) + + self._gradient_weight = np.asmatrix(self.xdata) + self._gradient_bias = -1 + self._gradient_x = self.weight + + self.gradient_weight = np.dot(gradient.T,self._gradient_weight.T) + self.gradient_bias = gradient * self._gradient_bias + self.gradient = np.dot(gradient,self._gradient_x).T + # ----------------------upgrade + # -----------the Negative gradient direction -------- + self.weight = self.weight - self.learn_rate * self.gradient_weight + self.bias = self.bias - self.learn_rate * self.gradient_bias.T + + return self.gradient + + +class BPNN(): + ''' + Back Propagation Neural Network model + ''' + def __init__(self): + self.layers = [] + self.train_mse = [] + self.fig_loss = plt.figure() + self.ax_loss = self.fig_loss.add_subplot(1,1,1) + + def add_layer(self,layer): + self.layers.append(layer) + + def build(self): + for i,layer in enumerate(self.layers[:]): + if i < 1: + layer.is_input_layer = True + else: + layer.initializer(self.layers[i-1].units) + + def summary(self): + for i,layer in enumerate(self.layers[:]): + print('------- layer %d -------'%i) + print('weight.shape ',np.shape(layer.weight)) + print('bias.shape ',np.shape(layer.bias)) + + def train(self,xdata,ydata,train_round,accuracy): + self.train_round = train_round + self.accuracy = accuracy + + self.ax_loss.hlines(self.accuracy, 0, self.train_round * 1.1) + + x_shape = np.shape(xdata) + for round_i in range(train_round): + all_loss = 0 + for row in range(x_shape[0]): + _xdata = np.asmatrix(xdata[row,:]).T + _ydata = np.asmatrix(ydata[row,:]).T + + # forward propagation + for layer in self.layers: + _xdata = layer.forward_propagation(_xdata) + + loss, gradient = self.cal_loss(_ydata, _xdata) + all_loss = all_loss + loss + + # back propagation + # the input_layer does not upgrade + for layer in self.layers[:0:-1]: + gradient = layer.back_propagation(gradient) + + mse = all_loss/x_shape[0] + self.train_mse.append(mse) + + self.plot_loss() + + if mse < self.accuracy: + print('----达到精度----') + return mse + + def cal_loss(self,ydata,ydata_): + self.loss = np.sum(np.power((ydata - ydata_),2)) + self.loss_gradient = 2 * (ydata_ - ydata) + # vector (shape is the same as _ydata.shape) + return self.loss,self.loss_gradient + + def plot_loss(self): + if self.ax_loss.lines: + self.ax_loss.lines.remove(self.ax_loss.lines[0]) + self.ax_loss.plot(self.train_mse, 'r-') + plt.ion() + plt.show() + plt.pause(0.1) + + + + +def example(): + + x = np.random.randn(10,10) + y = np.asarray([[0.8,0.4],[0.4,0.3],[0.34,0.45],[0.67,0.32], + [0.88,0.67],[0.78,0.77],[0.55,0.66],[0.55,0.43],[0.54,0.1], + [0.1,0.5]]) + + model = BPNN() + model.add_layer(DenseLayer(10)) + model.add_layer(DenseLayer(20)) + model.add_layer(DenseLayer(30)) + model.add_layer(DenseLayer(2)) + + model.build() + + model.summary() + + model.train(xdata=x,ydata=y,train_round=100,accuracy=0.01) + +if __name__ == '__main__': + example() diff --git a/neural_network/convolution_neural_network.py b/neural_network/convolution_neural_network.py new file mode 100644 index 000000000..0dca2bc48 --- /dev/null +++ b/neural_network/convolution_neural_network.py @@ -0,0 +1,306 @@ +#-*- coding: utf-8 -*- + +''' + - - - - - -- - - - - - - - - - - - - - - - - - - - - - - + Name - - CNN - Convolution Neural Network For Photo Recognizing + Goal - - Recognize Handing Writting Word Photo + Detail:Total 5 layers neural network + * Convolution layer + * Pooling layer + * Input layer layer of BP + * Hiden layer of BP + * Output layer of BP + Author: Stephen Lee + Github: 245885195@qq.com + Date: 2017.9.20 + - - - - - -- - - - - - - - - - - - - - - - - - - - - - - + ''' +from __future__ import print_function + +import numpy as np +import matplotlib.pyplot as plt + +class CNN(): + + def __init__(self,conv1_get,size_p1,bp_num1,bp_num2,bp_num3,rate_w=0.2,rate_t=0.2): + ''' + :param conv1_get: [a,c,d],size, number, step of convolution kernel + :param size_p1: pooling size + :param bp_num1: units number of flatten layer + :param bp_num2: units number of hidden layer + :param bp_num3: units number of output layer + :param rate_w: rate of weight learning + :param rate_t: rate of threshold learning + ''' + self.num_bp1 = bp_num1 + self.num_bp2 = bp_num2 + self.num_bp3 = bp_num3 + self.conv1 = conv1_get[:2] + self.step_conv1 = conv1_get[2] + self.size_pooling1 = size_p1 + self.rate_weight = rate_w + self.rate_thre = rate_t + self.w_conv1 = [np.mat(-1*np.random.rand(self.conv1[0],self.conv1[0])+0.5) for i in range(self.conv1[1])] + self.wkj = np.mat(-1 * np.random.rand(self.num_bp3, self.num_bp2) + 0.5) + self.vji = np.mat(-1*np.random.rand(self.num_bp2, self.num_bp1)+0.5) + self.thre_conv1 = -2*np.random.rand(self.conv1[1])+1 + self.thre_bp2 = -2*np.random.rand(self.num_bp2)+1 + self.thre_bp3 = -2*np.random.rand(self.num_bp3)+1 + + + def save_model(self,save_path): + #save model dict with pickle + import pickle + model_dic = {'num_bp1':self.num_bp1, + 'num_bp2':self.num_bp2, + 'num_bp3':self.num_bp3, + 'conv1':self.conv1, + 'step_conv1':self.step_conv1, + 'size_pooling1':self.size_pooling1, + 'rate_weight':self.rate_weight, + 'rate_thre':self.rate_thre, + 'w_conv1':self.w_conv1, + 'wkj':self.wkj, + 'vji':self.vji, + 'thre_conv1':self.thre_conv1, + 'thre_bp2':self.thre_bp2, + 'thre_bp3':self.thre_bp3} + with open(save_path, 'wb') as f: + pickle.dump(model_dic, f) + + print('Model saved: %s'% save_path) + + @classmethod + def ReadModel(cls,model_path): + #read saved model + import pickle + with open(model_path, 'rb') as f: + model_dic = pickle.load(f) + + conv_get= model_dic.get('conv1') + conv_get.append(model_dic.get('step_conv1')) + size_p1 = model_dic.get('size_pooling1') + bp1 = model_dic.get('num_bp1') + bp2 = model_dic.get('num_bp2') + bp3 = model_dic.get('num_bp3') + r_w = model_dic.get('rate_weight') + r_t = model_dic.get('rate_thre') + #create model instance + conv_ins = CNN(conv_get,size_p1,bp1,bp2,bp3,r_w,r_t) + #modify model parameter + conv_ins.w_conv1 = model_dic.get('w_conv1') + conv_ins.wkj = model_dic.get('wkj') + conv_ins.vji = model_dic.get('vji') + conv_ins.thre_conv1 = model_dic.get('thre_conv1') + conv_ins.thre_bp2 = model_dic.get('thre_bp2') + conv_ins.thre_bp3 = model_dic.get('thre_bp3') + return conv_ins + + + def sig(self,x): + return 1 / (1 + np.exp(-1*x)) + + def do_round(self,x): + return round(x, 3) + + def convolute(self,data,convs,w_convs,thre_convs,conv_step): + #convolution process + size_conv = convs[0] + num_conv =convs[1] + size_data = np.shape(data)[0] + #get the data slice of original image data, data_focus + data_focus = [] + for i_focus in range(0, size_data - size_conv + 1, conv_step): + for j_focus in range(0, size_data - size_conv + 1, conv_step): + focus = data[i_focus:i_focus + size_conv, j_focus:j_focus + size_conv] + data_focus.append(focus) + #caculate the feature map of every single kernel, and saved as list of matrix + data_featuremap = [] + Size_FeatureMap = int((size_data - size_conv) / conv_step + 1) + for i_map in range(num_conv): + featuremap = [] + for i_focus in range(len(data_focus)): + net_focus = np.sum(np.multiply(data_focus[i_focus], w_convs[i_map])) - thre_convs[i_map] + featuremap.append(self.sig(net_focus)) + featuremap = np.asmatrix(featuremap).reshape(Size_FeatureMap, Size_FeatureMap) + data_featuremap.append(featuremap) + + #expanding the data slice to One dimenssion + focus1_list = [] + for each_focus in data_focus: + focus1_list.extend(self.Expand_Mat(each_focus)) + focus_list = np.asarray(focus1_list) + return focus_list,data_featuremap + + def pooling(self,featuremaps,size_pooling,type='average_pool'): + #pooling process + size_map = len(featuremaps[0]) + size_pooled = int(size_map/size_pooling) + featuremap_pooled = [] + for i_map in range(len(featuremaps)): + map = featuremaps[i_map] + map_pooled = [] + for i_focus in range(0,size_map,size_pooling): + for j_focus in range(0, size_map, size_pooling): + focus = map[i_focus:i_focus + size_pooling, j_focus:j_focus + size_pooling] + if type == 'average_pool': + #average pooling + map_pooled.append(np.average(focus)) + elif type == 'max_pooling': + #max pooling + map_pooled.append(np.max(focus)) + map_pooled = np.asmatrix(map_pooled).reshape(size_pooled,size_pooled) + featuremap_pooled.append(map_pooled) + return featuremap_pooled + + def _expand(self,datas): + #expanding three dimension data to one dimension list + data_expanded = [] + for i in range(len(datas)): + shapes = np.shape(datas[i]) + data_listed = datas[i].reshape(1,shapes[0]*shapes[1]) + data_listed = data_listed.getA().tolist()[0] + data_expanded.extend(data_listed) + data_expanded = np.asarray(data_expanded) + return data_expanded + + def _expand_mat(self,data_mat): + #expanding matrix to one dimension list + data_mat = np.asarray(data_mat) + shapes = np.shape(data_mat) + data_expanded = data_mat.reshape(1,shapes[0]*shapes[1]) + return data_expanded + + def _calculate_gradient_from_pool(self,out_map,pd_pool,num_map,size_map,size_pooling): + ''' + calcluate the gradient from the data slice of pool layer + pd_pool: list of matrix + out_map: the shape of data slice(size_map*size_map) + return: pd_all: list of matrix, [num, size_map, size_map] + ''' + pd_all = [] + i_pool = 0 + for i_map in range(num_map): + pd_conv1 = np.ones((size_map, size_map)) + for i in range(0, size_map, size_pooling): + for j in range(0, size_map, size_pooling): + pd_conv1[i:i + size_pooling, j:j + size_pooling] = pd_pool[i_pool] + i_pool = i_pool + 1 + pd_conv2 = np.multiply(pd_conv1,np.multiply(out_map[i_map],(1-out_map[i_map]))) + pd_all.append(pd_conv2) + return pd_all + + def trian(self,patterns,datas_train, datas_teach, n_repeat, error_accuracy,draw_e = bool): + #model traning + print('----------------------Start Training-------------------------') + print((' - - Shape: Train_Data ',np.shape(datas_train))) + print((' - - Shape: Teach_Data ',np.shape(datas_teach))) + rp = 0 + all_mse = [] + mse = 10000 + while rp < n_repeat and mse >= error_accuracy: + alle = 0 + print('-------------Learning Time %d--------------'%rp) + for p in range(len(datas_train)): + #print('------------Learning Image: %d--------------'%p) + data_train = np.asmatrix(datas_train[p]) + data_teach = np.asarray(datas_teach[p]) + data_focus1,data_conved1 = self.convolute(data_train,self.conv1,self.w_conv1, + self.thre_conv1,conv_step=self.step_conv1) + data_pooled1 = self.pooling(data_conved1,self.size_pooling1) + shape_featuremap1 = np.shape(data_conved1) + ''' + print(' -----original shape ', np.shape(data_train)) + print(' ---- after convolution ',np.shape(data_conv1)) + print(' -----after pooling ',np.shape(data_pooled1)) + ''' + data_bp_input = self._expand(data_pooled1) + bp_out1 = data_bp_input + + bp_net_j = np.dot(bp_out1,self.vji.T) - self.thre_bp2 + bp_out2 = self.sig(bp_net_j) + bp_net_k = np.dot(bp_out2 ,self.wkj.T) - self.thre_bp3 + bp_out3 = self.sig(bp_net_k) + + #--------------Model Leaning ------------------------ + # calcluate error and gradient--------------- + pd_k_all = np.multiply((data_teach - bp_out3), np.multiply(bp_out3, (1 - bp_out3))) + pd_j_all = np.multiply(np.dot(pd_k_all,self.wkj), np.multiply(bp_out2, (1 - bp_out2))) + pd_i_all = np.dot(pd_j_all,self.vji) + + pd_conv1_pooled = pd_i_all / (self.size_pooling1*self.size_pooling1) + pd_conv1_pooled = pd_conv1_pooled.T.getA().tolist() + pd_conv1_all = self._calculate_gradient_from_pool(data_conved1,pd_conv1_pooled,shape_featuremap1[0], + shape_featuremap1[1],self.size_pooling1) + #weight and threshold learning process--------- + #convolution layer + for k_conv in range(self.conv1[1]): + pd_conv_list = self._expand_mat(pd_conv1_all[k_conv]) + delta_w = self.rate_weight * np.dot(pd_conv_list,data_focus1) + + self.w_conv1[k_conv] = self.w_conv1[k_conv] + delta_w.reshape((self.conv1[0],self.conv1[0])) + + self.thre_conv1[k_conv] = self.thre_conv1[k_conv] - np.sum(pd_conv1_all[k_conv]) * self.rate_thre + #all connected layer + self.wkj = self.wkj + pd_k_all.T * bp_out2 * self.rate_weight + self.vji = self.vji + pd_j_all.T * bp_out1 * self.rate_weight + self.thre_bp3 = self.thre_bp3 - pd_k_all * self.rate_thre + self.thre_bp2 = self.thre_bp2 - pd_j_all * self.rate_thre + # calculate the sum error of all single image + errors = np.sum(abs((data_teach - bp_out3))) + alle = alle + errors + #print(' ----Teach ',data_teach) + #print(' ----BP_output ',bp_out3) + rp = rp + 1 + mse = alle/patterns + all_mse.append(mse) + def draw_error(): + yplot = [error_accuracy for i in range(int(n_repeat * 1.2))] + plt.plot(all_mse, '+-') + plt.plot(yplot, 'r--') + plt.xlabel('Learning Times') + plt.ylabel('All_mse') + plt.grid(True, alpha=0.5) + plt.show() + print('------------------Training Complished---------------------') + print((' - - Training epoch: ', rp, ' - - Mse: %.6f' % mse)) + if draw_e: + draw_error() + return mse + + def predict(self,datas_test): + #model predict + produce_out = [] + print('-------------------Start Testing-------------------------') + print((' - - Shape: Test_Data ',np.shape(datas_test))) + for p in range(len(datas_test)): + data_test = np.asmatrix(datas_test[p]) + data_focus1, data_conved1 = self.convolute(data_test, self.conv1, self.w_conv1, + self.thre_conv1, conv_step=self.step_conv1) + data_pooled1 = self.pooling(data_conved1, self.size_pooling1) + data_bp_input = self._expand(data_pooled1) + + bp_out1 = data_bp_input + bp_net_j = bp_out1 * self.vji.T - self.thre_bp2 + bp_out2 = self.sig(bp_net_j) + bp_net_k = bp_out2 * self.wkj.T - self.thre_bp3 + bp_out3 = self.sig(bp_net_k) + produce_out.extend(bp_out3.getA().tolist()) + res = [list(map(self.do_round,each)) for each in produce_out] + return np.asarray(res) + + def convolution(self,data): + #return the data of image after convoluting process so we can check it out + data_test = np.asmatrix(data) + data_focus1, data_conved1 = self.convolute(data_test, self.conv1, self.w_conv1, + self.thre_conv1, conv_step=self.step_conv1) + data_pooled1 = self.pooling(data_conved1, self.size_pooling1) + + return data_conved1,data_pooled1 + + +if __name__ == '__main__': + pass + ''' + I will put the example on other file + ''' \ No newline at end of file diff --git a/neural_network/perceptron.py b/neural_network/perceptron.py new file mode 100644 index 000000000..16e632f8d --- /dev/null +++ b/neural_network/perceptron.py @@ -0,0 +1,124 @@ +''' + + Perceptron + w = w + N * (d(k) - y) * x(k) + + Using perceptron network for oil analysis, + with Measuring of 3 parameters that represent chemical characteristics we can classify the oil, in p1 or p2 + p1 = -1 + p2 = 1 + +''' +from __future__ import print_function + +import random + + +class Perceptron: + def __init__(self, sample, exit, learn_rate=0.01, epoch_number=1000, bias=-1): + self.sample = sample + self.exit = exit + self.learn_rate = learn_rate + self.epoch_number = epoch_number + self.bias = bias + self.number_sample = len(sample) + self.col_sample = len(sample[0]) + self.weight = [] + + def training(self): + for sample in self.sample: + sample.insert(0, self.bias) + + for i in range(self.col_sample): + self.weight.append(random.random()) + + self.weight.insert(0, self.bias) + + epoch_count = 0 + + while True: + erro = False + for i in range(self.number_sample): + u = 0 + for j in range(self.col_sample + 1): + u = u + self.weight[j] * self.sample[i][j] + y = self.sign(u) + if y != self.exit[i]: + + for j in range(self.col_sample + 1): + + self.weight[j] = self.weight[j] + self.learn_rate * (self.exit[i] - y) * self.sample[i][j] + erro = True + #print('Epoch: \n',epoch_count) + epoch_count = epoch_count + 1 + # if you want controle the epoch or just by erro + if erro == False: + print(('\nEpoch:\n',epoch_count)) + print('------------------------\n') + #if epoch_count > self.epoch_number or not erro: + break + + def sort(self, sample): + sample.insert(0, self.bias) + u = 0 + for i in range(self.col_sample + 1): + u = u + self.weight[i] * sample[i] + + y = self.sign(u) + + if y == -1: + print(('Sample: ', sample)) + print('classification: P1') + else: + print(('Sample: ', sample)) + print('classification: P2') + + def sign(self, u): + return 1 if u >= 0 else -1 + + +samples = [ + [-0.6508, 0.1097, 4.0009], + [-1.4492, 0.8896, 4.4005], + [2.0850, 0.6876, 12.0710], + [0.2626, 1.1476, 7.7985], + [0.6418, 1.0234, 7.0427], + [0.2569, 0.6730, 8.3265], + [1.1155, 0.6043, 7.4446], + [0.0914, 0.3399, 7.0677], + [0.0121, 0.5256, 4.6316], + [-0.0429, 0.4660, 5.4323], + [0.4340, 0.6870, 8.2287], + [0.2735, 1.0287, 7.1934], + [0.4839, 0.4851, 7.4850], + [0.4089, -0.1267, 5.5019], + [1.4391, 0.1614, 8.5843], + [-0.9115, -0.1973, 2.1962], + [0.3654, 1.0475, 7.4858], + [0.2144, 0.7515, 7.1699], + [0.2013, 1.0014, 6.5489], + [0.6483, 0.2183, 5.8991], + [-0.1147, 0.2242, 7.2435], + [-0.7970, 0.8795, 3.8762], + [-1.0625, 0.6366, 2.4707], + [0.5307, 0.1285, 5.6883], + [-1.2200, 0.7777, 1.7252], + [0.3957, 0.1076, 5.6623], + [-0.1013, 0.5989, 7.1812], + [2.4482, 0.9455, 11.2095], + [2.0149, 0.6192, 10.9263], + [0.2012, 0.2611, 5.4631] + +] + +exit = [-1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1] + +network = Perceptron(sample=samples, exit = exit, learn_rate=0.01, epoch_number=1000, bias=-1) + +network.trannig() + +while True: + sample = [] + for i in range(3): + sample.insert(i, float(raw_input('value: '))) + network.sort(sample) diff --git a/project_euler/Problem 01/sol1.py b/project_euler/Problem 01/sol1.py new file mode 100644 index 000000000..27031c3cf --- /dev/null +++ b/project_euler/Problem 01/sol1.py @@ -0,0 +1,17 @@ +''' +Problem Statement: +If we list all the natural numbers below 10 that are multiples of 3 or 5, +we get 3,5,6 and 9. The sum of these multiples is 23. +Find the sum of all the multiples of 3 or 5 below N. +''' +from __future__ import print_function +try: + raw_input # Python 2 +except NameError: + raw_input = input # Python 3 +n = int(raw_input().strip()) +sum=0 +for a in range(3,n): + if(a%3==0 or a%5==0): + sum+=a +print(sum) diff --git a/project_euler/Problem 01/sol2.py b/project_euler/Problem 01/sol2.py new file mode 100644 index 000000000..2b7760e0b --- /dev/null +++ b/project_euler/Problem 01/sol2.py @@ -0,0 +1,20 @@ +''' +Problem Statement: +If we list all the natural numbers below 10 that are multiples of 3 or 5, +we get 3,5,6 and 9. The sum of these multiples is 23. +Find the sum of all the multiples of 3 or 5 below N. +''' +from __future__ import print_function +try: + raw_input # Python 2 +except NameError: + raw_input = input # Python 3 +n = int(raw_input().strip()) +sum = 0 +terms = (n-1)//3 +sum+= ((terms)*(6+(terms-1)*3))//2 #sum of an A.P. +terms = (n-1)//5 +sum+= ((terms)*(10+(terms-1)*5))//2 +terms = (n-1)//15 +sum-= ((terms)*(30+(terms-1)*15))//2 +print(sum) diff --git a/project_euler/Problem 01/sol3.py b/project_euler/Problem 01/sol3.py new file mode 100644 index 000000000..f4f3aefcc --- /dev/null +++ b/project_euler/Problem 01/sol3.py @@ -0,0 +1,50 @@ +from __future__ import print_function + +''' +Problem Statement: +If we list all the natural numbers below 10 that are multiples of 3 or 5, +we get 3,5,6 and 9. The sum of these multiples is 23. +Find the sum of all the multiples of 3 or 5 below N. +''' +''' +This solution is based on the pattern that the successive numbers in the series follow: 0+3,+2,+1,+3,+1,+2,+3. +''' + +try: + raw_input # Python 2 +except NameError: + raw_input = input # Python 3 +n = int(raw_input().strip()) +sum=0 +num=0 +while(1): + num+=3 + if(num>=n): + break + sum+=num + num+=2 + if(num>=n): + break + sum+=num + num+=1 + if(num>=n): + break + sum+=num + num+=3 + if(num>=n): + break + sum+=num + num+=1 + if(num>=n): + break + sum+=num + num+=2 + if(num>=n): + break + sum+=num + num+=3 + if(num>=n): + break + sum+=num + +print(sum); diff --git a/project_euler/Problem 01/sol4.py b/project_euler/Problem 01/sol4.py new file mode 100644 index 000000000..7941f5fcd --- /dev/null +++ b/project_euler/Problem 01/sol4.py @@ -0,0 +1,30 @@ +def mulitples(limit): + xmulti = [] + zmulti = [] + z = 3 + x = 5 + temp = 1 + while True: + result = z * temp + if (result < limit): + zmulti.append(result) + temp += 1 + else: + temp = 1 + break + while True: + result = x * temp + if (result < limit): + xmulti.append(result) + temp += 1 + else: + break + collection = list(set(xmulti+zmulti)) + return (sum(collection)) + + + + + + +print (mulitples(1000)) diff --git a/project_euler/Problem 02/sol1.py b/project_euler/Problem 02/sol1.py new file mode 100644 index 000000000..f8257fb61 --- /dev/null +++ b/project_euler/Problem 02/sol1.py @@ -0,0 +1,26 @@ +''' +Problem: +Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, +the first 10 terms will be: + 1,2,3,5,8,13,21,34,55,89,.. +By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms. +e.g. for n=10, we have {2,8}, sum is 10. +''' +from __future__ import print_function + +try: + raw_input # Python 2 +except NameError: + raw_input = input # Python 3 + +n = int(raw_input().strip()) +i=1 +j=2 +sum=0 +while(j<=n): + if((j&1)==0): #can also use (j%2==0) + sum+=j + temp=i + i=j + j=temp+i +print(sum) diff --git a/project_euler/Problem 02/sol2.py b/project_euler/Problem 02/sol2.py new file mode 100644 index 000000000..aa8dc7f76 --- /dev/null +++ b/project_euler/Problem 02/sol2.py @@ -0,0 +1,12 @@ +def fib(n): + a, b, s = 0, 1, 0 + while b < n: + if b % 2 == 0 and b < n: s += b + a, b = b, a+b + ls.append(s) + +T = int(input().strip()) +ls = [] +for _ in range(T): + fib(int(input().strip())) +print(ls, sep = '\n') diff --git a/project_euler/Problem 02/sol3.py b/project_euler/Problem 02/sol3.py new file mode 100644 index 000000000..ede5e196b --- /dev/null +++ b/project_euler/Problem 02/sol3.py @@ -0,0 +1,20 @@ +''' +Problem: +Each new term in the Fibonacci sequence is generated by adding the previous two terms. + 0,1,1,2,3,5,8,13,21,34,55,89,.. +Every third term from 0 is even So using this I have written a simple code +By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms. +e.g. for n=10, we have {2,8}, sum is 10. +''' +"""Python 3""" +n = int(raw_input()) +a=0 +b=2 +count=0 +while 4*b+a1): + prime=n +print(prime) diff --git a/project_euler/Problem 04/sol1.py b/project_euler/Problem 04/sol1.py new file mode 100644 index 000000000..27490130c --- /dev/null +++ b/project_euler/Problem 04/sol1.py @@ -0,0 +1,29 @@ +''' +Problem: +A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99. +Find the largest palindrome made from the product of two 3-digit numbers which is less than N. +''' +from __future__ import print_function +limit = int(raw_input("limit? ")) + +# fetchs the next number +for number in range(limit-1,10000,-1): + + # converts number into string. + strNumber = str(number) + + # checks whether 'strNumber' is a palindrome. + if(strNumber == strNumber[::-1]): + + divisor = 999 + + # if 'number' is a product of two 3-digit numbers + # then number is the answer otherwise fetch next number. + while(divisor != 99): + + if((number % divisor == 0) and (len(str(number / divisor)) == 3)): + + print(number) + exit(0) + + divisor -=1 \ No newline at end of file diff --git a/project_euler/Problem 04/sol2.py b/project_euler/Problem 04/sol2.py new file mode 100644 index 000000000..a7e486d38 --- /dev/null +++ b/project_euler/Problem 04/sol2.py @@ -0,0 +1,19 @@ +''' +Problem: +A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99. +Find the largest palindrome made from the product of two 3-digit numbers which is less than N. +''' +from __future__ import print_function +arr = [] +for i in range(999,100,-1): + for j in range(999,100,-1): + t = str(i*j) + if t == t[::-1]: + arr.append(i*j) +arr.sort() + +n=int(raw_input()) +for i in arr[::-1]: + if(i LargestProduct: + LargestProduct = product + print(LargestProduct) + + +if __name__ == '__main__': + main() diff --git a/project_euler/Problem 09/sol1.py b/project_euler/Problem 09/sol1.py new file mode 100644 index 000000000..e54c543b4 --- /dev/null +++ b/project_euler/Problem 09/sol1.py @@ -0,0 +1,15 @@ +from __future__ import print_function +# Program to find the product of a,b,c which are Pythagorean Triplet that satisfice the following: +# 1. a < b < c +# 2. a**2 + b**2 = c**2 +# 3. a + b + c = 1000 + +print("Please Wait...") +for a in range(300): + for b in range(400): + for c in range(500): + if(a < b < c): + if((a**2) + (b**2) == (c**2)): + if((a+b+c) == 1000): + print(("Product of",a,"*",b,"*",c,"=",(a*b*c))) + break diff --git a/project_euler/Problem 09/sol2.py b/project_euler/Problem 09/sol2.py new file mode 100644 index 000000000..c02662d89 --- /dev/null +++ b/project_euler/Problem 09/sol2.py @@ -0,0 +1,18 @@ +"""A Pythagorean triplet is a set of three natural numbers, for which, +a^2+b^2=c^2 +Given N, Check if there exists any Pythagorean triplet for which a+b+c=N +Find maximum possible value of product of a,b,c among all such Pythagorean triplets, If there is no such Pythagorean triplet print -1.""" +#!/bin/python3 + +product=-1 +d=0 +N = int(raw_input()) +for a in range(1,N//3): + """Solving the two equations a**2+b**2=c**2 and a+b+c=N eliminating c """ + b=(N*N-2*a*N)//(2*N-2*a) + c=N-a-b + if c*c==(a*a+b*b): + d=(a*b*c) + if d>=product: + product=d +print(product) diff --git a/project_euler/Problem 10/sol1.py b/project_euler/Problem 10/sol1.py new file mode 100644 index 000000000..94e5b7362 --- /dev/null +++ b/project_euler/Problem 10/sol1.py @@ -0,0 +1,38 @@ +from __future__ import print_function +from math import sqrt + +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +def is_prime(n): + for i in xrange(2, int(sqrt(n))+1): + if n%i == 0: + return False + + return True + +def sum_of_primes(n): + if n > 2: + sumOfPrimes = 2 + else: + return 0 + + for i in xrange(3, n, 2): + if is_prime(i): + sumOfPrimes += i + + return sumOfPrimes + +if __name__ == '__main__': + import sys + + if len(sys.argv) == 1: + print(sum_of_primes(2000000)) + else: + try: + n = int(sys.argv[1]) + print(sum_of_primes(n)) + except ValueError: + print('Invalid entry - please enter a number.') diff --git a/project_euler/Problem 11/grid.txt b/project_euler/Problem 11/grid.txt new file mode 100644 index 000000000..1fc75c66a --- /dev/null +++ b/project_euler/Problem 11/grid.txt @@ -0,0 +1,20 @@ +08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 +49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 +81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 +52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 +22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 +24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 +32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 +67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 +24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 +21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 +78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 +16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 +86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 +19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 +04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 +88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 +04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 +20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 +20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 +01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 \ No newline at end of file diff --git a/project_euler/Problem 11/sol1.py b/project_euler/Problem 11/sol1.py new file mode 100644 index 000000000..b882dc449 --- /dev/null +++ b/project_euler/Problem 11/sol1.py @@ -0,0 +1,68 @@ +from __future__ import print_function +''' +What is the greatest product of four adjacent numbers (horizontally, vertically, or diagonally) in this 20x20 array? + +08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 +49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 +81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 +52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 +22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 +24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 +32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 +67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 +24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 +21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 +78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 +16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 +86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 +19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 +04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 +88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 +04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 +20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 +20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 +01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 +''' + +try: + xrange #Python 2 +except NameError: + xrange = range #Python 2 + +def largest_product(grid): + nColumns = len(grid[0]) + nRows = len(grid) + + largest = 0 + lrDiagProduct = 0 + rlDiagProduct = 0 + + #Check vertically, horizontally, diagonally at the same time (only works for nxn grid) + for i in xrange(nColumns): + for j in xrange(nRows-3): + vertProduct = grid[j][i]*grid[j+1][i]*grid[j+2][i]*grid[j+3][i] + horzProduct = grid[i][j]*grid[i][j+1]*grid[i][j+2]*grid[i][j+3] + + #Left-to-right diagonal (\) product + if (i < nColumns-3): + lrDiagProduct = grid[i][j]*grid[i+1][j+1]*grid[i+2][j+2]*grid[i+3][j+3] + + #Right-to-left diagonal(/) product + if (i > 2): + rlDiagProduct = grid[i][j]*grid[i-1][j+1]*grid[i-2][j+2]*grid[i-3][j+3] + + maxProduct = max(vertProduct, horzProduct, lrDiagProduct, rlDiagProduct) + if maxProduct > largest: + largest = maxProduct + + return largest + +if __name__ == '__main__': + grid = [] + with open('grid.txt') as file: + for line in file: + grid.append(line.strip('\n').split(' ')) + + grid = [[int(i) for i in grid[j]] for j in xrange(len(grid))] + + print(largest_product(grid)) \ No newline at end of file diff --git a/project_euler/Problem 11/sol2.py b/project_euler/Problem 11/sol2.py new file mode 100644 index 000000000..b03395f01 --- /dev/null +++ b/project_euler/Problem 11/sol2.py @@ -0,0 +1,39 @@ +def main(): + with open ("grid.txt", "r") as f: + l = [] + for i in range(20): + l.append([int(x) for x in f.readline().split()]) + + maximum = 0 + + # right + for i in range(20): + for j in range(17): + temp = l[i][j] * l[i][j+1] * l[i][j+2] * l[i][j+3] + if temp > maximum: + maximum = temp + + # down + for i in range(17): + for j in range(20): + temp = l[i][j] * l[i+1][j] * l[i+2][j] * l[i+3][j] + if temp > maximum: + maximum = temp + + #diagonal 1 + for i in range(17): + for j in range(17): + temp = l[i][j] * l[i+1][j+1] * l[i+2][j+2] * l[i+3][j+3] + if temp > maximum: + maximum = temp + + #diagonal 2 + for i in range(17): + for j in range(3, 20): + temp = l[i][j] * l[i+1][j-1] * l[i+2][j-2] * l[i+3][j-3] + if temp > maximum: + maximum = temp + print(maximum) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/project_euler/Problem 12/sol1.py b/project_euler/Problem 12/sol1.py new file mode 100644 index 000000000..9c4483fd6 --- /dev/null +++ b/project_euler/Problem 12/sol1.py @@ -0,0 +1,46 @@ +from __future__ import print_function +from math import sqrt +''' +Highly divisible triangular numbers +Problem 12 +The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be: + +1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... + +Let us list the factors of the first seven triangle numbers: + + 1: 1 + 3: 1,3 + 6: 1,2,3,6 +10: 1,2,5,10 +15: 1,3,5,15 +21: 1,3,7,21 +28: 1,2,4,7,14,28 +We can see that 28 is the first triangle number to have over five divisors. + +What is the value of the first triangle number to have over five hundred divisors? +''' +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +def count_divisors(n): + nDivisors = 0 + for i in xrange(1, int(sqrt(n))+1): + if n%i == 0: + nDivisors += 2 + + return nDivisors + +tNum = 1 +i = 1 + +while True: + i += 1 + tNum += i + + if count_divisors(tNum) > 500: + break + +print(tNum) \ No newline at end of file diff --git a/project_euler/Problem 13/sol1.py b/project_euler/Problem 13/sol1.py new file mode 100644 index 000000000..f041f0165 --- /dev/null +++ b/project_euler/Problem 13/sol1.py @@ -0,0 +1,14 @@ +''' +Problem Statement: +Work out the first ten digits of the sum of the N 50-digit numbers. +''' +from __future__ import print_function + +n = int(raw_input().strip()) + +array = [] +for i in range(n): + array.append(int(raw_input().strip())) + +print(str(sum(array))[:10]) + diff --git a/project_euler/Problem 14/sol1.py b/project_euler/Problem 14/sol1.py new file mode 100644 index 000000000..9037f6eb8 --- /dev/null +++ b/project_euler/Problem 14/sol1.py @@ -0,0 +1,21 @@ +from __future__ import print_function +largest_number = 0 +pre_counter = 0 + +for input1 in range(750000,1000000): + counter = 1 + number = input1 + + while number > 1: + if number % 2 == 0: + number /=2 + counter += 1 + else: + number = (3*number)+1 + counter += 1 + + if counter > pre_counter: + largest_number = input1 + pre_counter = counter + +print(('Largest Number:',largest_number,'->',pre_counter,'digits')) diff --git a/project_euler/Problem 15/sol1.py b/project_euler/Problem 15/sol1.py new file mode 100644 index 000000000..d24748011 --- /dev/null +++ b/project_euler/Problem 15/sol1.py @@ -0,0 +1,20 @@ +from __future__ import print_function +from math import factorial + +def lattice_paths(n): + n = 2*n #middle entry of odd rows starting at row 3 is the solution for n = 1, 2, 3,... + k = n/2 + + return factorial(n)/(factorial(k)*factorial(n-k)) + +if __name__ == '__main__': + import sys + + if len(sys.argv) == 1: + print(lattice_paths(20)) + else: + try: + n = int(sys.argv[1]) + print(lattice_paths(n)) + except ValueError: + print('Invalid entry - please enter a number.') diff --git a/project_euler/Problem 16/sol1.py b/project_euler/Problem 16/sol1.py new file mode 100644 index 000000000..dfd7c9ae3 --- /dev/null +++ b/project_euler/Problem 16/sol1.py @@ -0,0 +1,15 @@ +power = int(raw_input("Enter the power of 2: ")) +num = 2**power + +string_num = str(num) + +list_num = list(string_num) + +sum_of_num = 0 + +print("2 ^",power,"=",num) + +for i in list_num: + sum_of_num += int(i) + +print("Sum of the digits are:",sum_of_num) diff --git a/project_euler/Problem 17/sol1.py b/project_euler/Problem 17/sol1.py new file mode 100644 index 000000000..9de5d80b9 --- /dev/null +++ b/project_euler/Problem 17/sol1.py @@ -0,0 +1,35 @@ +from __future__ import print_function +''' +Number letter counts +Problem 17 + +If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total. + +If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used? + + +NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) +contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage. +''' + +ones_counts = [0, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8] #number of letters in zero, one, two, ..., nineteen (0 for zero since it's never said aloud) +tens_counts = [0, 0, 6, 6, 5, 5, 5, 7, 6, 6] #number of letters in twenty, thirty, ..., ninety (0 for numbers less than 20 due to inconsistency in teens) + +count = 0 + +for i in range(1, 1001): + if i < 1000: + if i >= 100: + count += ones_counts[i/100] + 7 #add number of letters for "n hundred" + + if i%100 is not 0: + count += 3 #add number of letters for "and" if number is not multiple of 100 + + if 0 < i%100 < 20: + count += ones_counts[i%100] #add number of letters for one, two, three, ..., nineteen (could be combined with below if not for inconsistency in teens) + else: + count += ones_counts[i%10] + tens_counts[(i%100-i%10)/10] #add number of letters for twenty, twenty one, ..., ninety nine + else: + count += ones_counts[i/1000] + 8 + +print(count) \ No newline at end of file diff --git a/project_euler/Problem 19/sol1.py b/project_euler/Problem 19/sol1.py new file mode 100644 index 000000000..94cf11702 --- /dev/null +++ b/project_euler/Problem 19/sol1.py @@ -0,0 +1,51 @@ +from __future__ import print_function +''' +Counting Sundays +Problem 19 + +You are given the following information, but you may prefer to do some research for yourself. + +1 Jan 1900 was a Monday. +Thirty days has September, +April, June and November. +All the rest have thirty-one, +Saving February alone, +Which has twenty-eight, rain or shine. +And on leap years, twenty-nine. + +A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400. + +How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)? +''' + +days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + +day = 6 +month = 1 +year = 1901 + +sundays = 0 + +while year < 2001: + day += 7 + + if (year%4 == 0 and not year%100 == 0) or (year%400 == 0): + if day > days_per_month[month-1] and month is not 2: + month += 1 + day = day-days_per_month[month-2] + elif day > 29 and month is 2: + month += 1 + day = day-29 + else: + if day > days_per_month[month-1]: + month += 1 + day = day-days_per_month[month-2] + + if month > 12: + year += 1 + month = 1 + + if year < 2001 and day is 1: + sundays += 1 + +print(sundays) \ No newline at end of file diff --git a/project_euler/Problem 20/sol1.py b/project_euler/Problem 20/sol1.py new file mode 100644 index 000000000..b347eb1f0 --- /dev/null +++ b/project_euler/Problem 20/sol1.py @@ -0,0 +1,27 @@ +# Finding the factorial. +def factorial(n): + fact = 1 + for i in range(1,n+1): + fact *= i + return fact + +# Spliting the digits and adding it. +def split_and_add(number): + sum_of_digits = 0 + while(number>0): + last_digit = number % 10 + sum_of_digits += last_digit + number = int(number/10) # Removing the last_digit from the given number. + return sum_of_digits + +# Taking the user input. +number = int(raw_input("Enter the Number: ")) + +# Assigning the factorial from the factorial function. +factorial = factorial(number) + +# Spliting and adding the factorial into answer. +answer = split_and_add(factorial) + +# Printing the answer. +print(answer) diff --git a/project_euler/Problem 20/sol2.py b/project_euler/Problem 20/sol2.py new file mode 100644 index 000000000..bca9af9cb --- /dev/null +++ b/project_euler/Problem 20/sol2.py @@ -0,0 +1,5 @@ +from math import factorial +def main(): + print(sum([int(x) for x in str(factorial(100))])) +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/project_euler/Problem 21/sol1.py b/project_euler/Problem 21/sol1.py new file mode 100644 index 000000000..6d137a7d4 --- /dev/null +++ b/project_euler/Problem 21/sol1.py @@ -0,0 +1,42 @@ +#-.- coding: latin-1 -.- +from __future__ import print_function +from math import sqrt +''' +Amicable Numbers +Problem 21 + +Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n). +If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers. + +For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220. + +Evaluate the sum of all the amicable numbers under 10000. +''' +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +def sum_of_divisors(n): + total = 0 + for i in xrange(1, int(sqrt(n)+1)): + if n%i == 0 and i != sqrt(n): + total += i + n//i + elif i == sqrt(n): + total += i + + return total-n + +sums = [] +total = 0 + +for i in xrange(1, 10000): + n = sum_of_divisors(i) + + if n < len(sums): + if sums[n-1] == i: + total += n + i + + sums.append(n) + +print(total) \ No newline at end of file diff --git a/project_euler/Problem 22/p022_names.txt b/project_euler/Problem 22/p022_names.txt new file mode 100644 index 000000000..7b8986bf6 --- /dev/null +++ b/project_euler/Problem 22/p022_names.txt @@ -0,0 +1 @@ +"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER","MARIA","SUSAN","MARGARET","DOROTHY","LISA","NANCY","KAREN","BETTY","HELEN","SANDRA","DONNA","CAROL","RUTH","SHARON","MICHELLE","LAURA","SARAH","KIMBERLY","DEBORAH","JESSICA","SHIRLEY","CYNTHIA","ANGELA","MELISSA","BRENDA","AMY","ANNA","REBECCA","VIRGINIA","KATHLEEN","PAMELA","MARTHA","DEBRA","AMANDA","STEPHANIE","CAROLYN","CHRISTINE","MARIE","JANET","CATHERINE","FRANCES","ANN","JOYCE","DIANE","ALICE","JULIE","HEATHER","TERESA","DORIS","GLORIA","EVELYN","JEAN","CHERYL","MILDRED","KATHERINE","JOAN","ASHLEY","JUDITH","ROSE","JANICE","KELLY","NICOLE","JUDY","CHRISTINA","KATHY","THERESA","BEVERLY","DENISE","TAMMY","IRENE","JANE","LORI","RACHEL","MARILYN","ANDREA","KATHRYN","LOUISE","SARA","ANNE","JACQUELINE","WANDA","BONNIE","JULIA","RUBY","LOIS","TINA","PHYLLIS","NORMA","PAULA","DIANA","ANNIE","LILLIAN","EMILY","ROBIN","PEGGY","CRYSTAL","GLADYS","RITA","DAWN","CONNIE","FLORENCE","TRACY","EDNA","TIFFANY","CARMEN","ROSA","CINDY","GRACE","WENDY","VICTORIA","EDITH","KIM","SHERRY","SYLVIA","JOSEPHINE","THELMA","SHANNON","SHEILA","ETHEL","ELLEN","ELAINE","MARJORIE","CARRIE","CHARLOTTE","MONICA","ESTHER","PAULINE","EMMA","JUANITA","ANITA","RHONDA","HAZEL","AMBER","EVA","DEBBIE","APRIL","LESLIE","CLARA","LUCILLE","JAMIE","JOANNE","ELEANOR","VALERIE","DANIELLE","MEGAN","ALICIA","SUZANNE","MICHELE","GAIL","BERTHA","DARLENE","VERONICA","JILL","ERIN","GERALDINE","LAUREN","CATHY","JOANN","LORRAINE","LYNN","SALLY","REGINA","ERICA","BEATRICE","DOLORES","BERNICE","AUDREY","YVONNE","ANNETTE","JUNE","SAMANTHA","MARION","DANA","STACY","ANA","RENEE","IDA","VIVIAN","ROBERTA","HOLLY","BRITTANY","MELANIE","LORETTA","YOLANDA","JEANETTE","LAURIE","KATIE","KRISTEN","VANESSA","ALMA","SUE","ELSIE","BETH","JEANNE","VICKI","CARLA","TARA","ROSEMARY","EILEEN","TERRI","GERTRUDE","LUCY","TONYA","ELLA","STACEY","WILMA","GINA","KRISTIN","JESSIE","NATALIE","AGNES","VERA","WILLIE","CHARLENE","BESSIE","DELORES","MELINDA","PEARL","ARLENE","MAUREEN","COLLEEN","ALLISON","TAMARA","JOY","GEORGIA","CONSTANCE","LILLIE","CLAUDIA","JACKIE","MARCIA","TANYA","NELLIE","MINNIE","MARLENE","HEIDI","GLENDA","LYDIA","VIOLA","COURTNEY","MARIAN","STELLA","CAROLINE","DORA","JO","VICKIE","MATTIE","TERRY","MAXINE","IRMA","MABEL","MARSHA","MYRTLE","LENA","CHRISTY","DEANNA","PATSY","HILDA","GWENDOLYN","JENNIE","NORA","MARGIE","NINA","CASSANDRA","LEAH","PENNY","KAY","PRISCILLA","NAOMI","CAROLE","BRANDY","OLGA","BILLIE","DIANNE","TRACEY","LEONA","JENNY","FELICIA","SONIA","MIRIAM","VELMA","BECKY","BOBBIE","VIOLET","KRISTINA","TONI","MISTY","MAE","SHELLY","DAISY","RAMONA","SHERRI","ERIKA","KATRINA","CLAIRE","LINDSEY","LINDSAY","GENEVA","GUADALUPE","BELINDA","MARGARITA","SHERYL","CORA","FAYE","ADA","NATASHA","SABRINA","ISABEL","MARGUERITE","HATTIE","HARRIET","MOLLY","CECILIA","KRISTI","BRANDI","BLANCHE","SANDY","ROSIE","JOANNA","IRIS","EUNICE","ANGIE","INEZ","LYNDA","MADELINE","AMELIA","ALBERTA","GENEVIEVE","MONIQUE","JODI","JANIE","MAGGIE","KAYLA","SONYA","JAN","LEE","KRISTINE","CANDACE","FANNIE","MARYANN","OPAL","ALISON","YVETTE","MELODY","LUZ","SUSIE","OLIVIA","FLORA","SHELLEY","KRISTY","MAMIE","LULA","LOLA","VERNA","BEULAH","ANTOINETTE","CANDICE","JUANA","JEANNETTE","PAM","KELLI","HANNAH","WHITNEY","BRIDGET","KARLA","CELIA","LATOYA","PATTY","SHELIA","GAYLE","DELLA","VICKY","LYNNE","SHERI","MARIANNE","KARA","JACQUELYN","ERMA","BLANCA","MYRA","LETICIA","PAT","KRISTA","ROXANNE","ANGELICA","JOHNNIE","ROBYN","FRANCIS","ADRIENNE","ROSALIE","ALEXANDRA","BROOKE","BETHANY","SADIE","BERNADETTE","TRACI","JODY","KENDRA","JASMINE","NICHOLE","RACHAEL","CHELSEA","MABLE","ERNESTINE","MURIEL","MARCELLA","ELENA","KRYSTAL","ANGELINA","NADINE","KARI","ESTELLE","DIANNA","PAULETTE","LORA","MONA","DOREEN","ROSEMARIE","ANGEL","DESIREE","ANTONIA","HOPE","GINGER","JANIS","BETSY","CHRISTIE","FREDA","MERCEDES","MEREDITH","LYNETTE","TERI","CRISTINA","EULA","LEIGH","MEGHAN","SOPHIA","ELOISE","ROCHELLE","GRETCHEN","CECELIA","RAQUEL","HENRIETTA","ALYSSA","JANA","KELLEY","GWEN","KERRY","JENNA","TRICIA","LAVERNE","OLIVE","ALEXIS","TASHA","SILVIA","ELVIRA","CASEY","DELIA","SOPHIE","KATE","PATTI","LORENA","KELLIE","SONJA","LILA","LANA","DARLA","MAY","MINDY","ESSIE","MANDY","LORENE","ELSA","JOSEFINA","JEANNIE","MIRANDA","DIXIE","LUCIA","MARTA","FAITH","LELA","JOHANNA","SHARI","CAMILLE","TAMI","SHAWNA","ELISA","EBONY","MELBA","ORA","NETTIE","TABITHA","OLLIE","JAIME","WINIFRED","KRISTIE","MARINA","ALISHA","AIMEE","RENA","MYRNA","MARLA","TAMMIE","LATASHA","BONITA","PATRICE","RONDA","SHERRIE","ADDIE","FRANCINE","DELORIS","STACIE","ADRIANA","CHERI","SHELBY","ABIGAIL","CELESTE","JEWEL","CARA","ADELE","REBEKAH","LUCINDA","DORTHY","CHRIS","EFFIE","TRINA","REBA","SHAWN","SALLIE","AURORA","LENORA","ETTA","LOTTIE","KERRI","TRISHA","NIKKI","ESTELLA","FRANCISCA","JOSIE","TRACIE","MARISSA","KARIN","BRITTNEY","JANELLE","LOURDES","LAUREL","HELENE","FERN","ELVA","CORINNE","KELSEY","INA","BETTIE","ELISABETH","AIDA","CAITLIN","INGRID","IVA","EUGENIA","CHRISTA","GOLDIE","CASSIE","MAUDE","JENIFER","THERESE","FRANKIE","DENA","LORNA","JANETTE","LATONYA","CANDY","MORGAN","CONSUELO","TAMIKA","ROSETTA","DEBORA","CHERIE","POLLY","DINA","JEWELL","FAY","JILLIAN","DOROTHEA","NELL","TRUDY","ESPERANZA","PATRICA","KIMBERLEY","SHANNA","HELENA","CAROLINA","CLEO","STEFANIE","ROSARIO","OLA","JANINE","MOLLIE","LUPE","ALISA","LOU","MARIBEL","SUSANNE","BETTE","SUSANA","ELISE","CECILE","ISABELLE","LESLEY","JOCELYN","PAIGE","JONI","RACHELLE","LEOLA","DAPHNE","ALTA","ESTER","PETRA","GRACIELA","IMOGENE","JOLENE","KEISHA","LACEY","GLENNA","GABRIELA","KERI","URSULA","LIZZIE","KIRSTEN","SHANA","ADELINE","MAYRA","JAYNE","JACLYN","GRACIE","SONDRA","CARMELA","MARISA","ROSALIND","CHARITY","TONIA","BEATRIZ","MARISOL","CLARICE","JEANINE","SHEENA","ANGELINE","FRIEDA","LILY","ROBBIE","SHAUNA","MILLIE","CLAUDETTE","CATHLEEN","ANGELIA","GABRIELLE","AUTUMN","KATHARINE","SUMMER","JODIE","STACI","LEA","CHRISTI","JIMMIE","JUSTINE","ELMA","LUELLA","MARGRET","DOMINIQUE","SOCORRO","RENE","MARTINA","MARGO","MAVIS","CALLIE","BOBBI","MARITZA","LUCILE","LEANNE","JEANNINE","DEANA","AILEEN","LORIE","LADONNA","WILLA","MANUELA","GALE","SELMA","DOLLY","SYBIL","ABBY","LARA","DALE","IVY","DEE","WINNIE","MARCY","LUISA","JERI","MAGDALENA","OFELIA","MEAGAN","AUDRA","MATILDA","LEILA","CORNELIA","BIANCA","SIMONE","BETTYE","RANDI","VIRGIE","LATISHA","BARBRA","GEORGINA","ELIZA","LEANN","BRIDGETTE","RHODA","HALEY","ADELA","NOLA","BERNADINE","FLOSSIE","ILA","GRETA","RUTHIE","NELDA","MINERVA","LILLY","TERRIE","LETHA","HILARY","ESTELA","VALARIE","BRIANNA","ROSALYN","EARLINE","CATALINA","AVA","MIA","CLARISSA","LIDIA","CORRINE","ALEXANDRIA","CONCEPCION","TIA","SHARRON","RAE","DONA","ERICKA","JAMI","ELNORA","CHANDRA","LENORE","NEVA","MARYLOU","MELISA","TABATHA","SERENA","AVIS","ALLIE","SOFIA","JEANIE","ODESSA","NANNIE","HARRIETT","LORAINE","PENELOPE","MILAGROS","EMILIA","BENITA","ALLYSON","ASHLEE","TANIA","TOMMIE","ESMERALDA","KARINA","EVE","PEARLIE","ZELMA","MALINDA","NOREEN","TAMEKA","SAUNDRA","HILLARY","AMIE","ALTHEA","ROSALINDA","JORDAN","LILIA","ALANA","GAY","CLARE","ALEJANDRA","ELINOR","MICHAEL","LORRIE","JERRI","DARCY","EARNESTINE","CARMELLA","TAYLOR","NOEMI","MARCIE","LIZA","ANNABELLE","LOUISA","EARLENE","MALLORY","CARLENE","NITA","SELENA","TANISHA","KATY","JULIANNE","JOHN","LAKISHA","EDWINA","MARICELA","MARGERY","KENYA","DOLLIE","ROXIE","ROSLYN","KATHRINE","NANETTE","CHARMAINE","LAVONNE","ILENE","KRIS","TAMMI","SUZETTE","CORINE","KAYE","JERRY","MERLE","CHRYSTAL","LINA","DEANNE","LILIAN","JULIANA","ALINE","LUANN","KASEY","MARYANNE","EVANGELINE","COLETTE","MELVA","LAWANDA","YESENIA","NADIA","MADGE","KATHIE","EDDIE","OPHELIA","VALERIA","NONA","MITZI","MARI","GEORGETTE","CLAUDINE","FRAN","ALISSA","ROSEANN","LAKEISHA","SUSANNA","REVA","DEIDRE","CHASITY","SHEREE","CARLY","JAMES","ELVIA","ALYCE","DEIRDRE","GENA","BRIANA","ARACELI","KATELYN","ROSANNE","WENDI","TESSA","BERTA","MARVA","IMELDA","MARIETTA","MARCI","LEONOR","ARLINE","SASHA","MADELYN","JANNA","JULIETTE","DEENA","AURELIA","JOSEFA","AUGUSTA","LILIANA","YOUNG","CHRISTIAN","LESSIE","AMALIA","SAVANNAH","ANASTASIA","VILMA","NATALIA","ROSELLA","LYNNETTE","CORINA","ALFREDA","LEANNA","CAREY","AMPARO","COLEEN","TAMRA","AISHA","WILDA","KARYN","CHERRY","QUEEN","MAURA","MAI","EVANGELINA","ROSANNA","HALLIE","ERNA","ENID","MARIANA","LACY","JULIET","JACKLYN","FREIDA","MADELEINE","MARA","HESTER","CATHRYN","LELIA","CASANDRA","BRIDGETT","ANGELITA","JANNIE","DIONNE","ANNMARIE","KATINA","BERYL","PHOEBE","MILLICENT","KATHERYN","DIANN","CARISSA","MARYELLEN","LIZ","LAURI","HELGA","GILDA","ADRIAN","RHEA","MARQUITA","HOLLIE","TISHA","TAMERA","ANGELIQUE","FRANCESCA","BRITNEY","KAITLIN","LOLITA","FLORINE","ROWENA","REYNA","TWILA","FANNY","JANELL","INES","CONCETTA","BERTIE","ALBA","BRIGITTE","ALYSON","VONDA","PANSY","ELBA","NOELLE","LETITIA","KITTY","DEANN","BRANDIE","LOUELLA","LETA","FELECIA","SHARLENE","LESA","BEVERLEY","ROBERT","ISABELLA","HERMINIA","TERRA","CELINA","TORI","OCTAVIA","JADE","DENICE","GERMAINE","SIERRA","MICHELL","CORTNEY","NELLY","DORETHA","SYDNEY","DEIDRA","MONIKA","LASHONDA","JUDI","CHELSEY","ANTIONETTE","MARGOT","BOBBY","ADELAIDE","NAN","LEEANN","ELISHA","DESSIE","LIBBY","KATHI","GAYLA","LATANYA","MINA","MELLISA","KIMBERLEE","JASMIN","RENAE","ZELDA","ELDA","MA","JUSTINA","GUSSIE","EMILIE","CAMILLA","ABBIE","ROCIO","KAITLYN","JESSE","EDYTHE","ASHLEIGH","SELINA","LAKESHA","GERI","ALLENE","PAMALA","MICHAELA","DAYNA","CARYN","ROSALIA","SUN","JACQULINE","REBECA","MARYBETH","KRYSTLE","IOLA","DOTTIE","BENNIE","BELLE","AUBREY","GRISELDA","ERNESTINA","ELIDA","ADRIANNE","DEMETRIA","DELMA","CHONG","JAQUELINE","DESTINY","ARLEEN","VIRGINA","RETHA","FATIMA","TILLIE","ELEANORE","CARI","TREVA","BIRDIE","WILHELMINA","ROSALEE","MAURINE","LATRICE","YONG","JENA","TARYN","ELIA","DEBBY","MAUDIE","JEANNA","DELILAH","CATRINA","SHONDA","HORTENCIA","THEODORA","TERESITA","ROBBIN","DANETTE","MARYJANE","FREDDIE","DELPHINE","BRIANNE","NILDA","DANNA","CINDI","BESS","IONA","HANNA","ARIEL","WINONA","VIDA","ROSITA","MARIANNA","WILLIAM","RACHEAL","GUILLERMINA","ELOISA","CELESTINE","CAREN","MALISSA","LONA","CHANTEL","SHELLIE","MARISELA","LEORA","AGATHA","SOLEDAD","MIGDALIA","IVETTE","CHRISTEN","ATHENA","JANEL","CHLOE","VEDA","PATTIE","TESSIE","TERA","MARILYNN","LUCRETIA","KARRIE","DINAH","DANIELA","ALECIA","ADELINA","VERNICE","SHIELA","PORTIA","MERRY","LASHAWN","DEVON","DARA","TAWANA","OMA","VERDA","CHRISTIN","ALENE","ZELLA","SANDI","RAFAELA","MAYA","KIRA","CANDIDA","ALVINA","SUZAN","SHAYLA","LYN","LETTIE","ALVA","SAMATHA","ORALIA","MATILDE","MADONNA","LARISSA","VESTA","RENITA","INDIA","DELOIS","SHANDA","PHILLIS","LORRI","ERLINDA","CRUZ","CATHRINE","BARB","ZOE","ISABELL","IONE","GISELA","CHARLIE","VALENCIA","ROXANNA","MAYME","KISHA","ELLIE","MELLISSA","DORRIS","DALIA","BELLA","ANNETTA","ZOILA","RETA","REINA","LAURETTA","KYLIE","CHRISTAL","PILAR","CHARLA","ELISSA","TIFFANI","TANA","PAULINA","LEOTA","BREANNA","JAYME","CARMEL","VERNELL","TOMASA","MANDI","DOMINGA","SANTA","MELODIE","LURA","ALEXA","TAMELA","RYAN","MIRNA","KERRIE","VENUS","NOEL","FELICITA","CRISTY","CARMELITA","BERNIECE","ANNEMARIE","TIARA","ROSEANNE","MISSY","CORI","ROXANA","PRICILLA","KRISTAL","JUNG","ELYSE","HAYDEE","ALETHA","BETTINA","MARGE","GILLIAN","FILOMENA","CHARLES","ZENAIDA","HARRIETTE","CARIDAD","VADA","UNA","ARETHA","PEARLINE","MARJORY","MARCELA","FLOR","EVETTE","ELOUISE","ALINA","TRINIDAD","DAVID","DAMARIS","CATHARINE","CARROLL","BELVA","NAKIA","MARLENA","LUANNE","LORINE","KARON","DORENE","DANITA","BRENNA","TATIANA","SAMMIE","LOUANN","LOREN","JULIANNA","ANDRIA","PHILOMENA","LUCILA","LEONORA","DOVIE","ROMONA","MIMI","JACQUELIN","GAYE","TONJA","MISTI","JOE","GENE","CHASTITY","STACIA","ROXANN","MICAELA","NIKITA","MEI","VELDA","MARLYS","JOHNNA","AURA","LAVERN","IVONNE","HAYLEY","NICKI","MAJORIE","HERLINDA","GEORGE","ALPHA","YADIRA","PERLA","GREGORIA","DANIEL","ANTONETTE","SHELLI","MOZELLE","MARIAH","JOELLE","CORDELIA","JOSETTE","CHIQUITA","TRISTA","LOUIS","LAQUITA","GEORGIANA","CANDI","SHANON","LONNIE","HILDEGARD","CECIL","VALENTINA","STEPHANY","MAGDA","KAROL","GERRY","GABRIELLA","TIANA","ROMA","RICHELLE","RAY","PRINCESS","OLETA","JACQUE","IDELLA","ALAINA","SUZANNA","JOVITA","BLAIR","TOSHA","RAVEN","NEREIDA","MARLYN","KYLA","JOSEPH","DELFINA","TENA","STEPHENIE","SABINA","NATHALIE","MARCELLE","GERTIE","DARLEEN","THEA","SHARONDA","SHANTEL","BELEN","VENESSA","ROSALINA","ONA","GENOVEVA","COREY","CLEMENTINE","ROSALBA","RENATE","RENATA","MI","IVORY","GEORGIANNA","FLOY","DORCAS","ARIANA","TYRA","THEDA","MARIAM","JULI","JESICA","DONNIE","VIKKI","VERLA","ROSELYN","MELVINA","JANNETTE","GINNY","DEBRAH","CORRIE","ASIA","VIOLETA","MYRTIS","LATRICIA","COLLETTE","CHARLEEN","ANISSA","VIVIANA","TWYLA","PRECIOUS","NEDRA","LATONIA","LAN","HELLEN","FABIOLA","ANNAMARIE","ADELL","SHARYN","CHANTAL","NIKI","MAUD","LIZETTE","LINDY","KIA","KESHA","JEANA","DANELLE","CHARLINE","CHANEL","CARROL","VALORIE","LIA","DORTHA","CRISTAL","SUNNY","LEONE","LEILANI","GERRI","DEBI","ANDRA","KESHIA","IMA","EULALIA","EASTER","DULCE","NATIVIDAD","LINNIE","KAMI","GEORGIE","CATINA","BROOK","ALDA","WINNIFRED","SHARLA","RUTHANN","MEAGHAN","MAGDALENE","LISSETTE","ADELAIDA","VENITA","TRENA","SHIRLENE","SHAMEKA","ELIZEBETH","DIAN","SHANTA","MICKEY","LATOSHA","CARLOTTA","WINDY","SOON","ROSINA","MARIANN","LEISA","JONNIE","DAWNA","CATHIE","BILLY","ASTRID","SIDNEY","LAUREEN","JANEEN","HOLLI","FAWN","VICKEY","TERESSA","SHANTE","RUBYE","MARCELINA","CHANDA","CARY","TERESE","SCARLETT","MARTY","MARNIE","LULU","LISETTE","JENIFFER","ELENOR","DORINDA","DONITA","CARMAN","BERNITA","ALTAGRACIA","ALETA","ADRIANNA","ZORAIDA","RONNIE","NICOLA","LYNDSEY","KENDALL","JANINA","CHRISSY","AMI","STARLA","PHYLIS","PHUONG","KYRA","CHARISSE","BLANCH","SANJUANITA","RONA","NANCI","MARILEE","MARANDA","CORY","BRIGETTE","SANJUANA","MARITA","KASSANDRA","JOYCELYN","IRA","FELIPA","CHELSIE","BONNY","MIREYA","LORENZA","KYONG","ILEANA","CANDELARIA","TONY","TOBY","SHERIE","OK","MARK","LUCIE","LEATRICE","LAKESHIA","GERDA","EDIE","BAMBI","MARYLIN","LAVON","HORTENSE","GARNET","EVIE","TRESSA","SHAYNA","LAVINA","KYUNG","JEANETTA","SHERRILL","SHARA","PHYLISS","MITTIE","ANABEL","ALESIA","THUY","TAWANDA","RICHARD","JOANIE","TIFFANIE","LASHANDA","KARISSA","ENRIQUETA","DARIA","DANIELLA","CORINNA","ALANNA","ABBEY","ROXANE","ROSEANNA","MAGNOLIA","LIDA","KYLE","JOELLEN","ERA","CORAL","CARLEEN","TRESA","PEGGIE","NOVELLA","NILA","MAYBELLE","JENELLE","CARINA","NOVA","MELINA","MARQUERITE","MARGARETTE","JOSEPHINA","EVONNE","DEVIN","CINTHIA","ALBINA","TOYA","TAWNYA","SHERITA","SANTOS","MYRIAM","LIZABETH","LISE","KEELY","JENNI","GISELLE","CHERYLE","ARDITH","ARDIS","ALESHA","ADRIANE","SHAINA","LINNEA","KAROLYN","HONG","FLORIDA","FELISHA","DORI","DARCI","ARTIE","ARMIDA","ZOLA","XIOMARA","VERGIE","SHAMIKA","NENA","NANNETTE","MAXIE","LOVIE","JEANE","JAIMIE","INGE","FARRAH","ELAINA","CAITLYN","STARR","FELICITAS","CHERLY","CARYL","YOLONDA","YASMIN","TEENA","PRUDENCE","PENNIE","NYDIA","MACKENZIE","ORPHA","MARVEL","LIZBETH","LAURETTE","JERRIE","HERMELINDA","CAROLEE","TIERRA","MIRIAN","META","MELONY","KORI","JENNETTE","JAMILA","ENA","ANH","YOSHIKO","SUSANNAH","SALINA","RHIANNON","JOLEEN","CRISTINE","ASHTON","ARACELY","TOMEKA","SHALONDA","MARTI","LACIE","KALA","JADA","ILSE","HAILEY","BRITTANI","ZONA","SYBLE","SHERRYL","RANDY","NIDIA","MARLO","KANDICE","KANDI","DEB","DEAN","AMERICA","ALYCIA","TOMMY","RONNA","NORENE","MERCY","JOSE","INGEBORG","GIOVANNA","GEMMA","CHRISTEL","AUDRY","ZORA","VITA","VAN","TRISH","STEPHAINE","SHIRLEE","SHANIKA","MELONIE","MAZIE","JAZMIN","INGA","HOA","HETTIE","GERALYN","FONDA","ESTRELLA","ADELLA","SU","SARITA","RINA","MILISSA","MARIBETH","GOLDA","EVON","ETHELYN","ENEDINA","CHERISE","CHANA","VELVA","TAWANNA","SADE","MIRTA","LI","KARIE","JACINTA","ELNA","DAVINA","CIERRA","ASHLIE","ALBERTHA","TANESHA","STEPHANI","NELLE","MINDI","LU","LORINDA","LARUE","FLORENE","DEMETRA","DEDRA","CIARA","CHANTELLE","ASHLY","SUZY","ROSALVA","NOELIA","LYDA","LEATHA","KRYSTYNA","KRISTAN","KARRI","DARLINE","DARCIE","CINDA","CHEYENNE","CHERRIE","AWILDA","ALMEDA","ROLANDA","LANETTE","JERILYN","GISELE","EVALYN","CYNDI","CLETA","CARIN","ZINA","ZENA","VELIA","TANIKA","PAUL","CHARISSA","THOMAS","TALIA","MARGARETE","LAVONDA","KAYLEE","KATHLENE","JONNA","IRENA","ILONA","IDALIA","CANDIS","CANDANCE","BRANDEE","ANITRA","ALIDA","SIGRID","NICOLETTE","MARYJO","LINETTE","HEDWIG","CHRISTIANA","CASSIDY","ALEXIA","TRESSIE","MODESTA","LUPITA","LITA","GLADIS","EVELIA","DAVIDA","CHERRI","CECILY","ASHELY","ANNABEL","AGUSTINA","WANITA","SHIRLY","ROSAURA","HULDA","EUN","BAILEY","YETTA","VERONA","THOMASINA","SIBYL","SHANNAN","MECHELLE","LUE","LEANDRA","LANI","KYLEE","KANDY","JOLYNN","FERNE","EBONI","CORENE","ALYSIA","ZULA","NADA","MOIRA","LYNDSAY","LORRETTA","JUAN","JAMMIE","HORTENSIA","GAYNELL","CAMERON","ADRIA","VINA","VICENTA","TANGELA","STEPHINE","NORINE","NELLA","LIANA","LESLEE","KIMBERELY","ILIANA","GLORY","FELICA","EMOGENE","ELFRIEDE","EDEN","EARTHA","CARMA","BEA","OCIE","MARRY","LENNIE","KIARA","JACALYN","CARLOTA","ARIELLE","YU","STAR","OTILIA","KIRSTIN","KACEY","JOHNETTA","JOEY","JOETTA","JERALDINE","JAUNITA","ELANA","DORTHEA","CAMI","AMADA","ADELIA","VERNITA","TAMAR","SIOBHAN","RENEA","RASHIDA","OUIDA","ODELL","NILSA","MERYL","KRISTYN","JULIETA","DANICA","BREANNE","AUREA","ANGLEA","SHERRON","ODETTE","MALIA","LORELEI","LIN","LEESA","KENNA","KATHLYN","FIONA","CHARLETTE","SUZIE","SHANTELL","SABRA","RACQUEL","MYONG","MIRA","MARTINE","LUCIENNE","LAVADA","JULIANN","JOHNIE","ELVERA","DELPHIA","CLAIR","CHRISTIANE","CHAROLETTE","CARRI","AUGUSTINE","ASHA","ANGELLA","PAOLA","NINFA","LEDA","LAI","EDA","SUNSHINE","STEFANI","SHANELL","PALMA","MACHELLE","LISSA","KECIA","KATHRYNE","KARLENE","JULISSA","JETTIE","JENNIFFER","HUI","CORRINA","CHRISTOPHER","CAROLANN","ALENA","TESS","ROSARIA","MYRTICE","MARYLEE","LIANE","KENYATTA","JUDIE","JANEY","IN","ELMIRA","ELDORA","DENNA","CRISTI","CATHI","ZAIDA","VONNIE","VIVA","VERNIE","ROSALINE","MARIELA","LUCIANA","LESLI","KARAN","FELICE","DENEEN","ADINA","WYNONA","TARSHA","SHERON","SHASTA","SHANITA","SHANI","SHANDRA","RANDA","PINKIE","PARIS","NELIDA","MARILOU","LYLA","LAURENE","LACI","JOI","JANENE","DOROTHA","DANIELE","DANI","CAROLYNN","CARLYN","BERENICE","AYESHA","ANNELIESE","ALETHEA","THERSA","TAMIKO","RUFINA","OLIVA","MOZELL","MARYLYN","MADISON","KRISTIAN","KATHYRN","KASANDRA","KANDACE","JANAE","GABRIEL","DOMENICA","DEBBRA","DANNIELLE","CHUN","BUFFY","BARBIE","ARCELIA","AJA","ZENOBIA","SHAREN","SHAREE","PATRICK","PAGE","MY","LAVINIA","KUM","KACIE","JACKELINE","HUONG","FELISA","EMELIA","ELEANORA","CYTHIA","CRISTIN","CLYDE","CLARIBEL","CARON","ANASTACIA","ZULMA","ZANDRA","YOKO","TENISHA","SUSANN","SHERILYN","SHAY","SHAWANDA","SABINE","ROMANA","MATHILDA","LINSEY","KEIKO","JOANA","ISELA","GRETTA","GEORGETTA","EUGENIE","DUSTY","DESIRAE","DELORA","CORAZON","ANTONINA","ANIKA","WILLENE","TRACEE","TAMATHA","REGAN","NICHELLE","MICKIE","MAEGAN","LUANA","LANITA","KELSIE","EDELMIRA","BREE","AFTON","TEODORA","TAMIE","SHENA","MEG","LINH","KELI","KACI","DANYELLE","BRITT","ARLETTE","ALBERTINE","ADELLE","TIFFINY","STORMY","SIMONA","NUMBERS","NICOLASA","NICHOL","NIA","NAKISHA","MEE","MAIRA","LOREEN","KIZZY","JOHNNY","JAY","FALLON","CHRISTENE","BOBBYE","ANTHONY","YING","VINCENZA","TANJA","RUBIE","RONI","QUEENIE","MARGARETT","KIMBERLI","IRMGARD","IDELL","HILMA","EVELINA","ESTA","EMILEE","DENNISE","DANIA","CARL","CARIE","ANTONIO","WAI","SANG","RISA","RIKKI","PARTICIA","MUI","MASAKO","MARIO","LUVENIA","LOREE","LONI","LIEN","KEVIN","GIGI","FLORENCIA","DORIAN","DENITA","DALLAS","CHI","BILLYE","ALEXANDER","TOMIKA","SHARITA","RANA","NIKOLE","NEOMA","MARGARITE","MADALYN","LUCINA","LAILA","KALI","JENETTE","GABRIELE","EVELYNE","ELENORA","CLEMENTINA","ALEJANDRINA","ZULEMA","VIOLETTE","VANNESSA","THRESA","RETTA","PIA","PATIENCE","NOELLA","NICKIE","JONELL","DELTA","CHUNG","CHAYA","CAMELIA","BETHEL","ANYA","ANDREW","THANH","SUZANN","SPRING","SHU","MILA","LILLA","LAVERNA","KEESHA","KATTIE","GIA","GEORGENE","EVELINE","ESTELL","ELIZBETH","VIVIENNE","VALLIE","TRUDIE","STEPHANE","MICHEL","MAGALY","MADIE","KENYETTA","KARREN","JANETTA","HERMINE","HARMONY","DRUCILLA","DEBBI","CELESTINA","CANDIE","BRITNI","BECKIE","AMINA","ZITA","YUN","YOLANDE","VIVIEN","VERNETTA","TRUDI","SOMMER","PEARLE","PATRINA","OSSIE","NICOLLE","LOYCE","LETTY","LARISA","KATHARINA","JOSELYN","JONELLE","JENELL","IESHA","HEIDE","FLORINDA","FLORENTINA","FLO","ELODIA","DORINE","BRUNILDA","BRIGID","ASHLI","ARDELLA","TWANA","THU","TARAH","SUNG","SHEA","SHAVON","SHANE","SERINA","RAYNA","RAMONITA","NGA","MARGURITE","LUCRECIA","KOURTNEY","KATI","JESUS","JESENIA","DIAMOND","CRISTA","AYANA","ALICA","ALIA","VINNIE","SUELLEN","ROMELIA","RACHELL","PIPER","OLYMPIA","MICHIKO","KATHALEEN","JOLIE","JESSI","JANESSA","HANA","HA","ELEASE","CARLETTA","BRITANY","SHONA","SALOME","ROSAMOND","REGENA","RAINA","NGOC","NELIA","LOUVENIA","LESIA","LATRINA","LATICIA","LARHONDA","JINA","JACKI","HOLLIS","HOLLEY","EMMY","DEEANN","CORETTA","ARNETTA","VELVET","THALIA","SHANICE","NETA","MIKKI","MICKI","LONNA","LEANA","LASHUNDA","KILEY","JOYE","JACQULYN","IGNACIA","HYUN","HIROKO","HENRY","HENRIETTE","ELAYNE","DELINDA","DARNELL","DAHLIA","COREEN","CONSUELA","CONCHITA","CELINE","BABETTE","AYANNA","ANETTE","ALBERTINA","SKYE","SHAWNEE","SHANEKA","QUIANA","PAMELIA","MIN","MERRI","MERLENE","MARGIT","KIESHA","KIERA","KAYLENE","JODEE","JENISE","ERLENE","EMMIE","ELSE","DARYL","DALILA","DAISEY","CODY","CASIE","BELIA","BABARA","VERSIE","VANESA","SHELBA","SHAWNDA","SAM","NORMAN","NIKIA","NAOMA","MARNA","MARGERET","MADALINE","LAWANA","KINDRA","JUTTA","JAZMINE","JANETT","HANNELORE","GLENDORA","GERTRUD","GARNETT","FREEDA","FREDERICA","FLORANCE","FLAVIA","DENNIS","CARLINE","BEVERLEE","ANJANETTE","VALDA","TRINITY","TAMALA","STEVIE","SHONNA","SHA","SARINA","ONEIDA","MICAH","MERILYN","MARLEEN","LURLINE","LENNA","KATHERIN","JIN","JENI","HAE","GRACIA","GLADY","FARAH","ERIC","ENOLA","EMA","DOMINQUE","DEVONA","DELANA","CECILA","CAPRICE","ALYSHA","ALI","ALETHIA","VENA","THERESIA","TAWNY","SONG","SHAKIRA","SAMARA","SACHIKO","RACHELE","PAMELLA","NICKY","MARNI","MARIEL","MAREN","MALISA","LIGIA","LERA","LATORIA","LARAE","KIMBER","KATHERN","KAREY","JENNEFER","JANETH","HALINA","FREDIA","DELISA","DEBROAH","CIERA","CHIN","ANGELIKA","ANDREE","ALTHA","YEN","VIVAN","TERRESA","TANNA","SUK","SUDIE","SOO","SIGNE","SALENA","RONNI","REBBECCA","MYRTIE","MCKENZIE","MALIKA","MAIDA","LOAN","LEONARDA","KAYLEIGH","FRANCE","ETHYL","ELLYN","DAYLE","CAMMIE","BRITTNI","BIRGIT","AVELINA","ASUNCION","ARIANNA","AKIKO","VENICE","TYESHA","TONIE","TIESHA","TAKISHA","STEFFANIE","SINDY","SANTANA","MEGHANN","MANDA","MACIE","LADY","KELLYE","KELLEE","JOSLYN","JASON","INGER","INDIRA","GLINDA","GLENNIS","FERNANDA","FAUSTINA","ENEIDA","ELICIA","DOT","DIGNA","DELL","ARLETTA","ANDRE","WILLIA","TAMMARA","TABETHA","SHERRELL","SARI","REFUGIO","REBBECA","PAULETTA","NIEVES","NATOSHA","NAKITA","MAMMIE","KENISHA","KAZUKO","KASSIE","GARY","EARLEAN","DAPHINE","CORLISS","CLOTILDE","CAROLYNE","BERNETTA","AUGUSTINA","AUDREA","ANNIS","ANNABELL","YAN","TENNILLE","TAMICA","SELENE","SEAN","ROSANA","REGENIA","QIANA","MARKITA","MACY","LEEANNE","LAURINE","KYM","JESSENIA","JANITA","GEORGINE","GENIE","EMIKO","ELVIE","DEANDRA","DAGMAR","CORIE","COLLEN","CHERISH","ROMAINE","PORSHA","PEARLENE","MICHELINE","MERNA","MARGORIE","MARGARETTA","LORE","KENNETH","JENINE","HERMINA","FREDERICKA","ELKE","DRUSILLA","DORATHY","DIONE","DESIRE","CELENA","BRIGIDA","ANGELES","ALLEGRA","THEO","TAMEKIA","SYNTHIA","STEPHEN","SOOK","SLYVIA","ROSANN","REATHA","RAYE","MARQUETTA","MARGART","LING","LAYLA","KYMBERLY","KIANA","KAYLEEN","KATLYN","KARMEN","JOELLA","IRINA","EMELDA","ELENI","DETRA","CLEMMIE","CHERYLL","CHANTELL","CATHEY","ARNITA","ARLA","ANGLE","ANGELIC","ALYSE","ZOFIA","THOMASINE","TENNIE","SON","SHERLY","SHERLEY","SHARYL","REMEDIOS","PETRINA","NICKOLE","MYUNG","MYRLE","MOZELLA","LOUANNE","LISHA","LATIA","LANE","KRYSTA","JULIENNE","JOEL","JEANENE","JACQUALINE","ISAURA","GWENDA","EARLEEN","DONALD","CLEOPATRA","CARLIE","AUDIE","ANTONIETTA","ALISE","ALEX","VERDELL","VAL","TYLER","TOMOKO","THAO","TALISHA","STEVEN","SO","SHEMIKA","SHAUN","SCARLET","SAVANNA","SANTINA","ROSIA","RAEANN","ODILIA","NANA","MINNA","MAGAN","LYNELLE","LE","KARMA","JOEANN","IVANA","INELL","ILANA","HYE","HONEY","HEE","GUDRUN","FRANK","DREAMA","CRISSY","CHANTE","CARMELINA","ARVILLA","ARTHUR","ANNAMAE","ALVERA","ALEIDA","AARON","YEE","YANIRA","VANDA","TIANNA","TAM","STEFANIA","SHIRA","PERRY","NICOL","NANCIE","MONSERRATE","MINH","MELYNDA","MELANY","MATTHEW","LOVELLA","LAURE","KIRBY","KACY","JACQUELYNN","HYON","GERTHA","FRANCISCO","ELIANA","CHRISTENA","CHRISTEEN","CHARISE","CATERINA","CARLEY","CANDYCE","ARLENA","AMMIE","YANG","WILLETTE","VANITA","TUYET","TINY","SYREETA","SILVA","SCOTT","RONALD","PENNEY","NYLA","MICHAL","MAURICE","MARYAM","MARYA","MAGEN","LUDIE","LOMA","LIVIA","LANELL","KIMBERLIE","JULEE","DONETTA","DIEDRA","DENISHA","DEANE","DAWNE","CLARINE","CHERRYL","BRONWYN","BRANDON","ALLA","VALERY","TONDA","SUEANN","SORAYA","SHOSHANA","SHELA","SHARLEEN","SHANELLE","NERISSA","MICHEAL","MERIDITH","MELLIE","MAYE","MAPLE","MAGARET","LUIS","LILI","LEONILA","LEONIE","LEEANNA","LAVONIA","LAVERA","KRISTEL","KATHEY","KATHE","JUSTIN","JULIAN","JIMMY","JANN","ILDA","HILDRED","HILDEGARDE","GENIA","FUMIKO","EVELIN","ERMELINDA","ELLY","DUNG","DOLORIS","DIONNA","DANAE","BERNEICE","ANNICE","ALIX","VERENA","VERDIE","TRISTAN","SHAWNNA","SHAWANA","SHAUNNA","ROZELLA","RANDEE","RANAE","MILAGRO","LYNELL","LUISE","LOUIE","LOIDA","LISBETH","KARLEEN","JUNITA","JONA","ISIS","HYACINTH","HEDY","GWENN","ETHELENE","ERLINE","EDWARD","DONYA","DOMONIQUE","DELICIA","DANNETTE","CICELY","BRANDA","BLYTHE","BETHANN","ASHLYN","ANNALEE","ALLINE","YUKO","VELLA","TRANG","TOWANDA","TESHA","SHERLYN","NARCISA","MIGUELINA","MERI","MAYBELL","MARLANA","MARGUERITA","MADLYN","LUNA","LORY","LORIANN","LIBERTY","LEONORE","LEIGHANN","LAURICE","LATESHA","LARONDA","KATRICE","KASIE","KARL","KALEY","JADWIGA","GLENNIE","GEARLDINE","FRANCINA","EPIFANIA","DYAN","DORIE","DIEDRE","DENESE","DEMETRICE","DELENA","DARBY","CRISTIE","CLEORA","CATARINA","CARISA","BERNIE","BARBERA","ALMETA","TRULA","TEREASA","SOLANGE","SHEILAH","SHAVONNE","SANORA","ROCHELL","MATHILDE","MARGARETA","MAIA","LYNSEY","LAWANNA","LAUNA","KENA","KEENA","KATIA","JAMEY","GLYNDA","GAYLENE","ELVINA","ELANOR","DANUTA","DANIKA","CRISTEN","CORDIE","COLETTA","CLARITA","CARMON","BRYNN","AZUCENA","AUNDREA","ANGELE","YI","WALTER","VERLIE","VERLENE","TAMESHA","SILVANA","SEBRINA","SAMIRA","REDA","RAYLENE","PENNI","PANDORA","NORAH","NOMA","MIREILLE","MELISSIA","MARYALICE","LARAINE","KIMBERY","KARYL","KARINE","KAM","JOLANDA","JOHANA","JESUSA","JALEESA","JAE","JACQUELYNE","IRISH","ILUMINADA","HILARIA","HANH","GENNIE","FRANCIE","FLORETTA","EXIE","EDDA","DREMA","DELPHA","BEV","BARBAR","ASSUNTA","ARDELL","ANNALISA","ALISIA","YUKIKO","YOLANDO","WONDA","WEI","WALTRAUD","VETA","TEQUILA","TEMEKA","TAMEIKA","SHIRLEEN","SHENITA","PIEDAD","OZELLA","MIRTHA","MARILU","KIMIKO","JULIANE","JENICE","JEN","JANAY","JACQUILINE","HILDE","FE","FAE","EVAN","EUGENE","ELOIS","ECHO","DEVORAH","CHAU","BRINDA","BETSEY","ARMINDA","ARACELIS","APRYL","ANNETT","ALISHIA","VEOLA","USHA","TOSHIKO","THEOLA","TASHIA","TALITHA","SHERY","RUDY","RENETTA","REIKO","RASHEEDA","OMEGA","OBDULIA","MIKA","MELAINE","MEGGAN","MARTIN","MARLEN","MARGET","MARCELINE","MANA","MAGDALEN","LIBRADA","LEZLIE","LEXIE","LATASHIA","LASANDRA","KELLE","ISIDRA","ISA","INOCENCIA","GWYN","FRANCOISE","ERMINIA","ERINN","DIMPLE","DEVORA","CRISELDA","ARMANDA","ARIE","ARIANE","ANGELO","ANGELENA","ALLEN","ALIZA","ADRIENE","ADALINE","XOCHITL","TWANNA","TRAN","TOMIKO","TAMISHA","TAISHA","SUSY","SIU","RUTHA","ROXY","RHONA","RAYMOND","OTHA","NORIKO","NATASHIA","MERRIE","MELVIN","MARINDA","MARIKO","MARGERT","LORIS","LIZZETTE","LEISHA","KAILA","KA","JOANNIE","JERRICA","JENE","JANNET","JANEE","JACINDA","HERTA","ELENORE","DORETTA","DELAINE","DANIELL","CLAUDIE","CHINA","BRITTA","APOLONIA","AMBERLY","ALEASE","YURI","YUK","WEN","WANETA","UTE","TOMI","SHARRI","SANDIE","ROSELLE","REYNALDA","RAGUEL","PHYLICIA","PATRIA","OLIMPIA","ODELIA","MITZIE","MITCHELL","MISS","MINDA","MIGNON","MICA","MENDY","MARIVEL","MAILE","LYNETTA","LAVETTE","LAURYN","LATRISHA","LAKIESHA","KIERSTEN","KARY","JOSPHINE","JOLYN","JETTA","JANISE","JACQUIE","IVELISSE","GLYNIS","GIANNA","GAYNELLE","EMERALD","DEMETRIUS","DANYELL","DANILLE","DACIA","CORALEE","CHER","CEOLA","BRETT","BELL","ARIANNE","ALESHIA","YUNG","WILLIEMAE","TROY","TRINH","THORA","TAI","SVETLANA","SHERIKA","SHEMEKA","SHAUNDA","ROSELINE","RICKI","MELDA","MALLIE","LAVONNA","LATINA","LARRY","LAQUANDA","LALA","LACHELLE","KLARA","KANDIS","JOHNA","JEANMARIE","JAYE","HANG","GRAYCE","GERTUDE","EMERITA","EBONIE","CLORINDA","CHING","CHERY","CAROLA","BREANN","BLOSSOM","BERNARDINE","BECKI","ARLETHA","ARGELIA","ARA","ALITA","YULANDA","YON","YESSENIA","TOBI","TASIA","SYLVIE","SHIRL","SHIRELY","SHERIDAN","SHELLA","SHANTELLE","SACHA","ROYCE","REBECKA","REAGAN","PROVIDENCIA","PAULENE","MISHA","MIKI","MARLINE","MARICA","LORITA","LATOYIA","LASONYA","KERSTIN","KENDA","KEITHA","KATHRIN","JAYMIE","JACK","GRICELDA","GINETTE","ERYN","ELINA","ELFRIEDA","DANYEL","CHEREE","CHANELLE","BARRIE","AVERY","AURORE","ANNAMARIA","ALLEEN","AILENE","AIDE","YASMINE","VASHTI","VALENTINE","TREASA","TORY","TIFFANEY","SHERYLL","SHARIE","SHANAE","SAU","RAISA","PA","NEDA","MITSUKO","MIRELLA","MILDA","MARYANNA","MARAGRET","MABELLE","LUETTA","LORINA","LETISHA","LATARSHA","LANELLE","LAJUANA","KRISSY","KARLY","KARENA","JON","JESSIKA","JERICA","JEANELLE","JANUARY","JALISA","JACELYN","IZOLA","IVEY","GREGORY","EUNA","ETHA","DREW","DOMITILA","DOMINICA","DAINA","CREOLA","CARLI","CAMIE","BUNNY","BRITTNY","ASHANTI","ANISHA","ALEEN","ADAH","YASUKO","WINTER","VIKI","VALRIE","TONA","TINISHA","THI","TERISA","TATUM","TANEKA","SIMONNE","SHALANDA","SERITA","RESSIE","REFUGIA","PAZ","OLENE","NA","MERRILL","MARGHERITA","MANDIE","MAN","MAIRE","LYNDIA","LUCI","LORRIANE","LORETA","LEONIA","LAVONA","LASHAWNDA","LAKIA","KYOKO","KRYSTINA","KRYSTEN","KENIA","KELSI","JUDE","JEANICE","ISOBEL","GEORGIANN","GENNY","FELICIDAD","EILENE","DEON","DELOISE","DEEDEE","DANNIE","CONCEPTION","CLORA","CHERILYN","CHANG","CALANDRA","BERRY","ARMANDINA","ANISA","ULA","TIMOTHY","TIERA","THERESSA","STEPHANIA","SIMA","SHYLA","SHONTA","SHERA","SHAQUITA","SHALA","SAMMY","ROSSANA","NOHEMI","NERY","MORIAH","MELITA","MELIDA","MELANI","MARYLYNN","MARISHA","MARIETTE","MALORIE","MADELENE","LUDIVINA","LORIA","LORETTE","LORALEE","LIANNE","LEON","LAVENIA","LAURINDA","LASHON","KIT","KIMI","KEILA","KATELYNN","KAI","JONE","JOANE","JI","JAYNA","JANELLA","JA","HUE","HERTHA","FRANCENE","ELINORE","DESPINA","DELSIE","DEEDRA","CLEMENCIA","CARRY","CAROLIN","CARLOS","BULAH","BRITTANIE","BOK","BLONDELL","BIBI","BEAULAH","BEATA","ANNITA","AGRIPINA","VIRGEN","VALENE","UN","TWANDA","TOMMYE","TOI","TARRA","TARI","TAMMERA","SHAKIA","SADYE","RUTHANNE","ROCHEL","RIVKA","PURA","NENITA","NATISHA","MING","MERRILEE","MELODEE","MARVIS","LUCILLA","LEENA","LAVETA","LARITA","LANIE","KEREN","ILEEN","GEORGEANN","GENNA","GENESIS","FRIDA","EWA","EUFEMIA","EMELY","ELA","EDYTH","DEONNA","DEADRA","DARLENA","CHANELL","CHAN","CATHERN","CASSONDRA","CASSAUNDRA","BERNARDA","BERNA","ARLINDA","ANAMARIA","ALBERT","WESLEY","VERTIE","VALERI","TORRI","TATYANA","STASIA","SHERISE","SHERILL","SEASON","SCOTTIE","SANDA","RUTHE","ROSY","ROBERTO","ROBBI","RANEE","QUYEN","PEARLY","PALMIRA","ONITA","NISHA","NIESHA","NIDA","NEVADA","NAM","MERLYN","MAYOLA","MARYLOUISE","MARYLAND","MARX","MARTH","MARGENE","MADELAINE","LONDA","LEONTINE","LEOMA","LEIA","LAWRENCE","LAURALEE","LANORA","LAKITA","KIYOKO","KETURAH","KATELIN","KAREEN","JONIE","JOHNETTE","JENEE","JEANETT","IZETTA","HIEDI","HEIKE","HASSIE","HAROLD","GIUSEPPINA","GEORGANN","FIDELA","FERNANDE","ELWANDA","ELLAMAE","ELIZ","DUSTI","DOTTY","CYNDY","CORALIE","CELESTA","ARGENTINA","ALVERTA","XENIA","WAVA","VANETTA","TORRIE","TASHINA","TANDY","TAMBRA","TAMA","STEPANIE","SHILA","SHAUNTA","SHARAN","SHANIQUA","SHAE","SETSUKO","SERAFINA","SANDEE","ROSAMARIA","PRISCILA","OLINDA","NADENE","MUOI","MICHELINA","MERCEDEZ","MARYROSE","MARIN","MARCENE","MAO","MAGALI","MAFALDA","LOGAN","LINN","LANNIE","KAYCE","KAROLINE","KAMILAH","KAMALA","JUSTA","JOLINE","JENNINE","JACQUETTA","IRAIDA","GERALD","GEORGEANNA","FRANCHESCA","FAIRY","EMELINE","ELANE","EHTEL","EARLIE","DULCIE","DALENE","CRIS","CLASSIE","CHERE","CHARIS","CAROYLN","CARMINA","CARITA","BRIAN","BETHANIE","AYAKO","ARICA","AN","ALYSA","ALESSANDRA","AKILAH","ADRIEN","ZETTA","YOULANDA","YELENA","YAHAIRA","XUAN","WENDOLYN","VICTOR","TIJUANA","TERRELL","TERINA","TERESIA","SUZI","SUNDAY","SHERELL","SHAVONDA","SHAUNTE","SHARDA","SHAKITA","SENA","RYANN","RUBI","RIVA","REGINIA","REA","RACHAL","PARTHENIA","PAMULA","MONNIE","MONET","MICHAELE","MELIA","MARINE","MALKA","MAISHA","LISANDRA","LEO","LEKISHA","LEAN","LAURENCE","LAKENDRA","KRYSTIN","KORTNEY","KIZZIE","KITTIE","KERA","KENDAL","KEMBERLY","KANISHA","JULENE","JULE","JOSHUA","JOHANNE","JEFFREY","JAMEE","HAN","HALLEY","GIDGET","GALINA","FREDRICKA","FLETA","FATIMAH","EUSEBIA","ELZA","ELEONORE","DORTHEY","DORIA","DONELLA","DINORAH","DELORSE","CLARETHA","CHRISTINIA","CHARLYN","BONG","BELKIS","AZZIE","ANDERA","AIKO","ADENA","YER","YAJAIRA","WAN","VANIA","ULRIKE","TOSHIA","TIFANY","STEFANY","SHIZUE","SHENIKA","SHAWANNA","SHAROLYN","SHARILYN","SHAQUANA","SHANTAY","SEE","ROZANNE","ROSELEE","RICKIE","REMONA","REANNA","RAELENE","QUINN","PHUNG","PETRONILA","NATACHA","NANCEY","MYRL","MIYOKO","MIESHA","MERIDETH","MARVELLA","MARQUITTA","MARHTA","MARCHELLE","LIZETH","LIBBIE","LAHOMA","LADAWN","KINA","KATHELEEN","KATHARYN","KARISA","KALEIGH","JUNIE","JULIEANN","JOHNSIE","JANEAN","JAIMEE","JACKQUELINE","HISAKO","HERMA","HELAINE","GWYNETH","GLENN","GITA","EUSTOLIA","EMELINA","ELIN","EDRIS","DONNETTE","DONNETTA","DIERDRE","DENAE","DARCEL","CLAUDE","CLARISA","CINDERELLA","CHIA","CHARLESETTA","CHARITA","CELSA","CASSY","CASSI","CARLEE","BRUNA","BRITTANEY","BRANDE","BILLI","BAO","ANTONETTA","ANGLA","ANGELYN","ANALISA","ALANE","WENONA","WENDIE","VERONIQUE","VANNESA","TOBIE","TEMPIE","SUMIKO","SULEMA","SPARKLE","SOMER","SHEBA","SHAYNE","SHARICE","SHANEL","SHALON","SAGE","ROY","ROSIO","ROSELIA","RENAY","REMA","REENA","PORSCHE","PING","PEG","OZIE","ORETHA","ORALEE","ODA","NU","NGAN","NAKESHA","MILLY","MARYBELLE","MARLIN","MARIS","MARGRETT","MARAGARET","MANIE","LURLENE","LILLIA","LIESELOTTE","LAVELLE","LASHAUNDA","LAKEESHA","KEITH","KAYCEE","KALYN","JOYA","JOETTE","JENAE","JANIECE","ILLA","GRISEL","GLAYDS","GENEVIE","GALA","FREDDA","FRED","ELMER","ELEONOR","DEBERA","DEANDREA","DAN","CORRINNE","CORDIA","CONTESSA","COLENE","CLEOTILDE","CHARLOTT","CHANTAY","CECILLE","BEATRIS","AZALEE","ARLEAN","ARDATH","ANJELICA","ANJA","ALFREDIA","ALEISHA","ADAM","ZADA","YUONNE","XIAO","WILLODEAN","WHITLEY","VENNIE","VANNA","TYISHA","TOVA","TORIE","TONISHA","TILDA","TIEN","TEMPLE","SIRENA","SHERRIL","SHANTI","SHAN","SENAIDA","SAMELLA","ROBBYN","RENDA","REITA","PHEBE","PAULITA","NOBUKO","NGUYET","NEOMI","MOON","MIKAELA","MELANIA","MAXIMINA","MARG","MAISIE","LYNNA","LILLI","LAYNE","LASHAUN","LAKENYA","LAEL","KIRSTIE","KATHLINE","KASHA","KARLYN","KARIMA","JOVAN","JOSEFINE","JENNELL","JACQUI","JACKELYN","HYO","HIEN","GRAZYNA","FLORRIE","FLORIA","ELEONORA","DWANA","DORLA","DONG","DELMY","DEJA","DEDE","DANN","CRYSTA","CLELIA","CLARIS","CLARENCE","CHIEKO","CHERLYN","CHERELLE","CHARMAIN","CHARA","CAMMY","BEE","ARNETTE","ARDELLE","ANNIKA","AMIEE","AMEE","ALLENA","YVONE","YUKI","YOSHIE","YEVETTE","YAEL","WILLETTA","VONCILE","VENETTA","TULA","TONETTE","TIMIKA","TEMIKA","TELMA","TEISHA","TAREN","TA","STACEE","SHIN","SHAWNTA","SATURNINA","RICARDA","POK","PASTY","ONIE","NUBIA","MORA","MIKE","MARIELLE","MARIELLA","MARIANELA","MARDELL","MANY","LUANNA","LOISE","LISABETH","LINDSY","LILLIANA","LILLIAM","LELAH","LEIGHA","LEANORA","LANG","KRISTEEN","KHALILAH","KEELEY","KANDRA","JUNKO","JOAQUINA","JERLENE","JANI","JAMIKA","JAME","HSIU","HERMILA","GOLDEN","GENEVIVE","EVIA","EUGENA","EMMALINE","ELFREDA","ELENE","DONETTE","DELCIE","DEEANNA","DARCEY","CUC","CLARINDA","CIRA","CHAE","CELINDA","CATHERYN","CATHERIN","CASIMIRA","CARMELIA","CAMELLIA","BREANA","BOBETTE","BERNARDINA","BEBE","BASILIA","ARLYNE","AMAL","ALAYNA","ZONIA","ZENIA","YURIKO","YAEKO","WYNELL","WILLOW","WILLENA","VERNIA","TU","TRAVIS","TORA","TERRILYN","TERICA","TENESHA","TAWNA","TAJUANA","TAINA","STEPHNIE","SONA","SOL","SINA","SHONDRA","SHIZUKO","SHERLENE","SHERICE","SHARIKA","ROSSIE","ROSENA","RORY","RIMA","RIA","RHEBA","RENNA","PETER","NATALYA","NANCEE","MELODI","MEDA","MAXIMA","MATHA","MARKETTA","MARICRUZ","MARCELENE","MALVINA","LUBA","LOUETTA","LEIDA","LECIA","LAURAN","LASHAWNA","LAINE","KHADIJAH","KATERINE","KASI","KALLIE","JULIETTA","JESUSITA","JESTINE","JESSIA","JEREMY","JEFFIE","JANYCE","ISADORA","GEORGIANNE","FIDELIA","EVITA","EURA","EULAH","ESTEFANA","ELSY","ELIZABET","ELADIA","DODIE","DION","DIA","DENISSE","DELORAS","DELILA","DAYSI","DAKOTA","CURTIS","CRYSTLE","CONCHA","COLBY","CLARETTA","CHU","CHRISTIA","CHARLSIE","CHARLENA","CARYLON","BETTYANN","ASLEY","ASHLEA","AMIRA","AI","AGUEDA","AGNUS","YUETTE","VINITA","VICTORINA","TYNISHA","TREENA","TOCCARA","TISH","THOMASENA","TEGAN","SOILA","SHILOH","SHENNA","SHARMAINE","SHANTAE","SHANDI","SEPTEMBER","SARAN","SARAI","SANA","SAMUEL","SALLEY","ROSETTE","ROLANDE","REGINE","OTELIA","OSCAR","OLEVIA","NICHOLLE","NECOLE","NAIDA","MYRTA","MYESHA","MITSUE","MINTA","MERTIE","MARGY","MAHALIA","MADALENE","LOVE","LOURA","LOREAN","LEWIS","LESHA","LEONIDA","LENITA","LAVONE","LASHELL","LASHANDRA","LAMONICA","KIMBRA","KATHERINA","KARRY","KANESHA","JULIO","JONG","JENEVA","JAQUELYN","HWA","GILMA","GHISLAINE","GERTRUDIS","FRANSISCA","FERMINA","ETTIE","ETSUKO","ELLIS","ELLAN","ELIDIA","EDRA","DORETHEA","DOREATHA","DENYSE","DENNY","DEETTA","DAINE","CYRSTAL","CORRIN","CAYLA","CARLITA","CAMILA","BURMA","BULA","BUENA","BLAKE","BARABARA","AVRIL","AUSTIN","ALAINE","ZANA","WILHEMINA","WANETTA","VIRGIL","VI","VERONIKA","VERNON","VERLINE","VASILIKI","TONITA","TISA","TEOFILA","TAYNA","TAUNYA","TANDRA","TAKAKO","SUNNI","SUANNE","SIXTA","SHARELL","SEEMA","RUSSELL","ROSENDA","ROBENA","RAYMONDE","PEI","PAMILA","OZELL","NEIDA","NEELY","MISTIE","MICHA","MERISSA","MAURITA","MARYLN","MARYETTA","MARSHALL","MARCELL","MALENA","MAKEDA","MADDIE","LOVETTA","LOURIE","LORRINE","LORILEE","LESTER","LAURENA","LASHAY","LARRAINE","LAREE","LACRESHA","KRISTLE","KRISHNA","KEVA","KEIRA","KAROLE","JOIE","JINNY","JEANNETTA","JAMA","HEIDY","GILBERTE","GEMA","FAVIOLA","EVELYNN","ENDA","ELLI","ELLENA","DIVINA","DAGNY","COLLENE","CODI","CINDIE","CHASSIDY","CHASIDY","CATRICE","CATHERINA","CASSEY","CAROLL","CARLENA","CANDRA","CALISTA","BRYANNA","BRITTENY","BEULA","BARI","AUDRIE","AUDRIA","ARDELIA","ANNELLE","ANGILA","ALONA","ALLYN","DOUGLAS","ROGER","JONATHAN","RALPH","NICHOLAS","BENJAMIN","BRUCE","HARRY","WAYNE","STEVE","HOWARD","ERNEST","PHILLIP","TODD","CRAIG","ALAN","PHILIP","EARL","DANNY","BRYAN","STANLEY","LEONARD","NATHAN","MANUEL","RODNEY","MARVIN","VINCENT","JEFFERY","JEFF","CHAD","JACOB","ALFRED","BRADLEY","HERBERT","FREDERICK","EDWIN","DON","RICKY","RANDALL","BARRY","BERNARD","LEROY","MARCUS","THEODORE","CLIFFORD","MIGUEL","JIM","TOM","CALVIN","BILL","LLOYD","DEREK","WARREN","DARRELL","JEROME","FLOYD","ALVIN","TIM","GORDON","GREG","JORGE","DUSTIN","PEDRO","DERRICK","ZACHARY","HERMAN","GLEN","HECTOR","RICARDO","RICK","BRENT","RAMON","GILBERT","MARC","REGINALD","RUBEN","NATHANIEL","RAFAEL","EDGAR","MILTON","RAUL","BEN","CHESTER","DUANE","FRANKLIN","BRAD","RON","ROLAND","ARNOLD","HARVEY","JARED","ERIK","DARRYL","NEIL","JAVIER","FERNANDO","CLINTON","TED","MATHEW","TYRONE","DARREN","LANCE","KURT","ALLAN","NELSON","GUY","CLAYTON","HUGH","MAX","DWAYNE","DWIGHT","ARMANDO","FELIX","EVERETT","IAN","WALLACE","KEN","BOB","ALFREDO","ALBERTO","DAVE","IVAN","BYRON","ISAAC","MORRIS","CLIFTON","WILLARD","ROSS","ANDY","SALVADOR","KIRK","SERGIO","SETH","KENT","TERRANCE","EDUARDO","TERRENCE","ENRIQUE","WADE","STUART","FREDRICK","ARTURO","ALEJANDRO","NICK","LUTHER","WENDELL","JEREMIAH","JULIUS","OTIS","TREVOR","OLIVER","LUKE","HOMER","GERARD","DOUG","KENNY","HUBERT","LYLE","MATT","ALFONSO","ORLANDO","REX","CARLTON","ERNESTO","NEAL","PABLO","LORENZO","OMAR","WILBUR","GRANT","HORACE","RODERICK","ABRAHAM","WILLIS","RICKEY","ANDRES","CESAR","JOHNATHAN","MALCOLM","RUDOLPH","DAMON","KELVIN","PRESTON","ALTON","ARCHIE","MARCO","WM","PETE","RANDOLPH","GARRY","GEOFFREY","JONATHON","FELIPE","GERARDO","ED","DOMINIC","DELBERT","COLIN","GUILLERMO","EARNEST","LUCAS","BENNY","SPENCER","RODOLFO","MYRON","EDMUND","GARRETT","SALVATORE","CEDRIC","LOWELL","GREGG","SHERMAN","WILSON","SYLVESTER","ROOSEVELT","ISRAEL","JERMAINE","FORREST","WILBERT","LELAND","SIMON","CLARK","IRVING","BRYANT","OWEN","RUFUS","WOODROW","KRISTOPHER","MACK","LEVI","MARCOS","GUSTAVO","JAKE","LIONEL","GILBERTO","CLINT","NICOLAS","ISMAEL","ORVILLE","ERVIN","DEWEY","AL","WILFRED","JOSH","HUGO","IGNACIO","CALEB","TOMAS","SHELDON","ERICK","STEWART","DOYLE","DARREL","ROGELIO","TERENCE","SANTIAGO","ALONZO","ELIAS","BERT","ELBERT","RAMIRO","CONRAD","NOAH","GRADY","PHIL","CORNELIUS","LAMAR","ROLANDO","CLAY","PERCY","DEXTER","BRADFORD","DARIN","AMOS","MOSES","IRVIN","SAUL","ROMAN","RANDAL","TIMMY","DARRIN","WINSTON","BRENDAN","ABEL","DOMINICK","BOYD","EMILIO","ELIJAH","DOMINGO","EMMETT","MARLON","EMANUEL","JERALD","EDMOND","EMIL","DEWAYNE","WILL","OTTO","TEDDY","REYNALDO","BRET","JESS","TRENT","HUMBERTO","EMMANUEL","STEPHAN","VICENTE","LAMONT","GARLAND","MILES","EFRAIN","HEATH","RODGER","HARLEY","ETHAN","ELDON","ROCKY","PIERRE","JUNIOR","FREDDY","ELI","BRYCE","ANTOINE","STERLING","CHASE","GROVER","ELTON","CLEVELAND","DYLAN","CHUCK","DAMIAN","REUBEN","STAN","AUGUST","LEONARDO","JASPER","RUSSEL","ERWIN","BENITO","HANS","MONTE","BLAINE","ERNIE","CURT","QUENTIN","AGUSTIN","MURRAY","JAMAL","ADOLFO","HARRISON","TYSON","BURTON","BRADY","ELLIOTT","WILFREDO","BART","JARROD","VANCE","DENIS","DAMIEN","JOAQUIN","HARLAN","DESMOND","ELLIOT","DARWIN","GREGORIO","BUDDY","XAVIER","KERMIT","ROSCOE","ESTEBAN","ANTON","SOLOMON","SCOTTY","NORBERT","ELVIN","WILLIAMS","NOLAN","ROD","QUINTON","HAL","BRAIN","ROB","ELWOOD","KENDRICK","DARIUS","MOISES","FIDEL","THADDEUS","CLIFF","MARCEL","JACKSON","RAPHAEL","BRYON","ARMAND","ALVARO","JEFFRY","DANE","JOESPH","THURMAN","NED","RUSTY","MONTY","FABIAN","REGGIE","MASON","GRAHAM","ISAIAH","VAUGHN","GUS","LOYD","DIEGO","ADOLPH","NORRIS","MILLARD","ROCCO","GONZALO","DERICK","RODRIGO","WILEY","RIGOBERTO","ALPHONSO","TY","NOE","VERN","REED","JEFFERSON","ELVIS","BERNARDO","MAURICIO","HIRAM","DONOVAN","BASIL","RILEY","NICKOLAS","MAYNARD","SCOT","VINCE","QUINCY","EDDY","SEBASTIAN","FEDERICO","ULYSSES","HERIBERTO","DONNELL","COLE","DAVIS","GAVIN","EMERY","WARD","ROMEO","JAYSON","DANTE","CLEMENT","COY","MAXWELL","JARVIS","BRUNO","ISSAC","DUDLEY","BROCK","SANFORD","CARMELO","BARNEY","NESTOR","STEFAN","DONNY","ART","LINWOOD","BEAU","WELDON","GALEN","ISIDRO","TRUMAN","DELMAR","JOHNATHON","SILAS","FREDERIC","DICK","IRWIN","MERLIN","CHARLEY","MARCELINO","HARRIS","CARLO","TRENTON","KURTIS","HUNTER","AURELIO","WINFRED","VITO","COLLIN","DENVER","CARTER","LEONEL","EMORY","PASQUALE","MOHAMMAD","MARIANO","DANIAL","LANDON","DIRK","BRANDEN","ADAN","BUFORD","GERMAN","WILMER","EMERSON","ZACHERY","FLETCHER","JACQUES","ERROL","DALTON","MONROE","JOSUE","EDWARDO","BOOKER","WILFORD","SONNY","SHELTON","CARSON","THERON","RAYMUNDO","DAREN","HOUSTON","ROBBY","LINCOLN","GENARO","BENNETT","OCTAVIO","CORNELL","HUNG","ARRON","ANTONY","HERSCHEL","GIOVANNI","GARTH","CYRUS","CYRIL","RONNY","LON","FREEMAN","DUNCAN","KENNITH","CARMINE","ERICH","CHADWICK","WILBURN","RUSS","REID","MYLES","ANDERSON","MORTON","JONAS","FOREST","MITCHEL","MERVIN","ZANE","RICH","JAMEL","LAZARO","ALPHONSE","RANDELL","MAJOR","JARRETT","BROOKS","ABDUL","LUCIANO","SEYMOUR","EUGENIO","MOHAMMED","VALENTIN","CHANCE","ARNULFO","LUCIEN","FERDINAND","THAD","EZRA","ALDO","RUBIN","ROYAL","MITCH","EARLE","ABE","WYATT","MARQUIS","LANNY","KAREEM","JAMAR","BORIS","ISIAH","EMILE","ELMO","ARON","LEOPOLDO","EVERETTE","JOSEF","ELOY","RODRICK","REINALDO","LUCIO","JERROD","WESTON","HERSHEL","BARTON","PARKER","LEMUEL","BURT","JULES","GIL","ELISEO","AHMAD","NIGEL","EFREN","ANTWAN","ALDEN","MARGARITO","COLEMAN","DINO","OSVALDO","LES","DEANDRE","NORMAND","KIETH","TREY","NORBERTO","NAPOLEON","JEROLD","FRITZ","ROSENDO","MILFORD","CHRISTOPER","ALFONZO","LYMAN","JOSIAH","BRANT","WILTON","RICO","JAMAAL","DEWITT","BRENTON","OLIN","FOSTER","FAUSTINO","CLAUDIO","JUDSON","GINO","EDGARDO","ALEC","TANNER","JARRED","DONN","TAD","PRINCE","PORFIRIO","ODIS","LENARD","CHAUNCEY","TOD","MEL","MARCELO","KORY","AUGUSTUS","KEVEN","HILARIO","BUD","SAL","ORVAL","MAURO","ZACHARIAH","OLEN","ANIBAL","MILO","JED","DILLON","AMADO","NEWTON","LENNY","RICHIE","HORACIO","BRICE","MOHAMED","DELMER","DARIO","REYES","MAC","JONAH","JERROLD","ROBT","HANK","RUPERT","ROLLAND","KENTON","DAMION","ANTONE","WALDO","FREDRIC","BRADLY","KIP","BURL","WALKER","TYREE","JEFFEREY","AHMED","WILLY","STANFORD","OREN","NOBLE","MOSHE","MIKEL","ENOCH","BRENDON","QUINTIN","JAMISON","FLORENCIO","DARRICK","TOBIAS","HASSAN","GIUSEPPE","DEMARCUS","CLETUS","TYRELL","LYNDON","KEENAN","WERNER","GERALDO","COLUMBUS","CHET","BERTRAM","MARKUS","HUEY","HILTON","DWAIN","DONTE","TYRON","OMER","ISAIAS","HIPOLITO","FERMIN","ADALBERTO","BO","BARRETT","TEODORO","MCKINLEY","MAXIMO","GARFIELD","RALEIGH","LAWERENCE","ABRAM","RASHAD","KING","EMMITT","DARON","SAMUAL","MIQUEL","EUSEBIO","DOMENIC","DARRON","BUSTER","WILBER","RENATO","JC","HOYT","HAYWOOD","EZEKIEL","CHAS","FLORENTINO","ELROY","CLEMENTE","ARDEN","NEVILLE","EDISON","DESHAWN","NATHANIAL","JORDON","DANILO","CLAUD","SHERWOOD","RAYMON","RAYFORD","CRISTOBAL","AMBROSE","TITUS","HYMAN","FELTON","EZEQUIEL","ERASMO","STANTON","LONNY","LEN","IKE","MILAN","LINO","JAROD","HERB","ANDREAS","WALTON","RHETT","PALMER","DOUGLASS","CORDELL","OSWALDO","ELLSWORTH","VIRGILIO","TONEY","NATHANAEL","DEL","BENEDICT","MOSE","JOHNSON","ISREAL","GARRET","FAUSTO","ASA","ARLEN","ZACK","WARNER","MODESTO","FRANCESCO","MANUAL","GAYLORD","GASTON","FILIBERTO","DEANGELO","MICHALE","GRANVILLE","WES","MALIK","ZACKARY","TUAN","ELDRIDGE","CRISTOPHER","CORTEZ","ANTIONE","MALCOM","LONG","KOREY","JOSPEH","COLTON","WAYLON","VON","HOSEA","SHAD","SANTO","RUDOLF","ROLF","REY","RENALDO","MARCELLUS","LUCIUS","KRISTOFER","BOYCE","BENTON","HAYDEN","HARLAND","ARNOLDO","RUEBEN","LEANDRO","KRAIG","JERRELL","JEROMY","HOBERT","CEDRICK","ARLIE","WINFORD","WALLY","LUIGI","KENETH","JACINTO","GRAIG","FRANKLYN","EDMUNDO","SID","PORTER","LEIF","JERAMY","BUCK","WILLIAN","VINCENZO","SHON","LYNWOOD","JERE","HAI","ELDEN","DORSEY","DARELL","BRODERICK","ALONSO" \ No newline at end of file diff --git a/project_euler/Problem 22/sol1.py b/project_euler/Problem 22/sol1.py new file mode 100644 index 000000000..775430658 --- /dev/null +++ b/project_euler/Problem 22/sol1.py @@ -0,0 +1,37 @@ +# -*- coding: latin-1 -*- +from __future__ import print_function +''' +Name scores +Problem 22 + +Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it +into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list +to obtain a name score. + +For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. +So, COLIN would obtain a score of 938 × 53 = 49714. + +What is the total of all the name scores in the file? +''' +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +with open('p022_names.txt') as file: + names = str(file.readlines()[0]) + names = names.replace('"', '').split(',') + +names.sort() + +name_score = 0 +total_score = 0 + +for i, name in enumerate(names): + for letter in name: + name_score += ord(letter) - 64 + + total_score += (i+1)*name_score + name_score = 0 + +print(total_score) \ No newline at end of file diff --git a/project_euler/Problem 22/sol2.py b/project_euler/Problem 22/sol2.py new file mode 100644 index 000000000..d7f9abf09 --- /dev/null +++ b/project_euler/Problem 22/sol2.py @@ -0,0 +1,533 @@ +def main(): + name = [ + "MARY", "PATRICIA", "LINDA", "BARBARA", "ELIZABETH", "JENNIFER", "MARIA", "SUSAN", "MARGARET", "DOROTHY", + "LISA", "NANCY", "KAREN", "BETTY", "HELEN", "SANDRA", "DONNA", "CAROL", "RUTH", "SHARON", + "MICHELLE", "LAURA", "SARAH", "KIMBERLY", "DEBORAH", "JESSICA", "SHIRLEY", "CYNTHIA", "ANGELA", "MELISSA", + "BRENDA", "AMY", "ANNA", "REBECCA", "VIRGINIA", "KATHLEEN", "PAMELA", "MARTHA", "DEBRA", "AMANDA", + "STEPHANIE", "CAROLYN", "CHRISTINE", "MARIE", "JANET", "CATHERINE", "FRANCES", "ANN", "JOYCE", "DIANE", + "ALICE", "JULIE", "HEATHER", "TERESA", "DORIS", "GLORIA", "EVELYN", "JEAN", "CHERYL", "MILDRED", + "KATHERINE", "JOAN", "ASHLEY", "JUDITH", "ROSE", "JANICE", "KELLY", "NICOLE", "JUDY", "CHRISTINA", + "KATHY", "THERESA", "BEVERLY", "DENISE", "TAMMY", "IRENE", "JANE", "LORI", "RACHEL", "MARILYN", + "ANDREA", "KATHRYN", "LOUISE", "SARA", "ANNE", "JACQUELINE", "WANDA", "BONNIE", "JULIA", "RUBY", + "LOIS", "TINA", "PHYLLIS", "NORMA", "PAULA", "DIANA", "ANNIE", "LILLIAN", "EMILY", "ROBIN", + "PEGGY", "CRYSTAL", "GLADYS", "RITA", "DAWN", "CONNIE", "FLORENCE", "TRACY", "EDNA", "TIFFANY", + "CARMEN", "ROSA", "CINDY", "GRACE", "WENDY", "VICTORIA", "EDITH", "KIM", "SHERRY", "SYLVIA", + "JOSEPHINE", "THELMA", "SHANNON", "SHEILA", "ETHEL", "ELLEN", "ELAINE", "MARJORIE", "CARRIE", "CHARLOTTE", + "MONICA", "ESTHER", "PAULINE", "EMMA", "JUANITA", "ANITA", "RHONDA", "HAZEL", "AMBER", "EVA", + "DEBBIE", "APRIL", "LESLIE", "CLARA", "LUCILLE", "JAMIE", "JOANNE", "ELEANOR", "VALERIE", "DANIELLE", + "MEGAN", "ALICIA", "SUZANNE", "MICHELE", "GAIL", "BERTHA", "DARLENE", "VERONICA", "JILL", "ERIN", + "GERALDINE", "LAUREN", "CATHY", "JOANN", "LORRAINE", "LYNN", "SALLY", "REGINA", "ERICA", "BEATRICE", + "DOLORES", "BERNICE", "AUDREY", "YVONNE", "ANNETTE", "JUNE", "SAMANTHA", "MARION", "DANA", "STACY", + "ANA", "RENEE", "IDA", "VIVIAN", "ROBERTA", "HOLLY", "BRITTANY", "MELANIE", "LORETTA", "YOLANDA", + "JEANETTE", "LAURIE", "KATIE", "KRISTEN", "VANESSA", "ALMA", "SUE", "ELSIE", "BETH", "JEANNE", + "VICKI", "CARLA", "TARA", "ROSEMARY", "EILEEN", "TERRI", "GERTRUDE", "LUCY", "TONYA", "ELLA", + "STACEY", "WILMA", "GINA", "KRISTIN", "JESSIE", "NATALIE", "AGNES", "VERA", "WILLIE", "CHARLENE", + "BESSIE", "DELORES", "MELINDA", "PEARL", "ARLENE", "MAUREEN", "COLLEEN", "ALLISON", "TAMARA", "JOY", + "GEORGIA", "CONSTANCE", "LILLIE", "CLAUDIA", "JACKIE", "MARCIA", "TANYA", "NELLIE", "MINNIE", "MARLENE", + "HEIDI", "GLENDA", "LYDIA", "VIOLA", "COURTNEY", "MARIAN", "STELLA", "CAROLINE", "DORA", "JO", + "VICKIE", "MATTIE", "TERRY", "MAXINE", "IRMA", "MABEL", "MARSHA", "MYRTLE", "LENA", "CHRISTY", + "DEANNA", "PATSY", "HILDA", "GWENDOLYN", "JENNIE", "NORA", "MARGIE", "NINA", "CASSANDRA", "LEAH", + "PENNY", "KAY", "PRISCILLA", "NAOMI", "CAROLE", "BRANDY", "OLGA", "BILLIE", "DIANNE", "TRACEY", + "LEONA", "JENNY", "FELICIA", "SONIA", "MIRIAM", "VELMA", "BECKY", "BOBBIE", "VIOLET", "KRISTINA", + "TONI", "MISTY", "MAE", "SHELLY", "DAISY", "RAMONA", "SHERRI", "ERIKA", "KATRINA", "CLAIRE", + "LINDSEY", "LINDSAY", "GENEVA", "GUADALUPE", "BELINDA", "MARGARITA", "SHERYL", "CORA", "FAYE", "ADA", + "NATASHA", "SABRINA", "ISABEL", "MARGUERITE", "HATTIE", "HARRIET", "MOLLY", "CECILIA", "KRISTI", "BRANDI", + "BLANCHE", "SANDY", "ROSIE", "JOANNA", "IRIS", "EUNICE", "ANGIE", "INEZ", "LYNDA", "MADELINE", + "AMELIA", "ALBERTA", "GENEVIEVE", "MONIQUE", "JODI", "JANIE", "MAGGIE", "KAYLA", "SONYA", "JAN", + "LEE", "KRISTINE", "CANDACE", "FANNIE", "MARYANN", "OPAL", "ALISON", "YVETTE", "MELODY", "LUZ", + "SUSIE", "OLIVIA", "FLORA", "SHELLEY", "KRISTY", "MAMIE", "LULA", "LOLA", "VERNA", "BEULAH", + "ANTOINETTE", "CANDICE", "JUANA", "JEANNETTE", "PAM", "KELLI", "HANNAH", "WHITNEY", "BRIDGET", "KARLA", + "CELIA", "LATOYA", "PATTY", "SHELIA", "GAYLE", "DELLA", "VICKY", "LYNNE", "SHERI", "MARIANNE", + "KARA", "JACQUELYN", "ERMA", "BLANCA", "MYRA", "LETICIA", "PAT", "KRISTA", "ROXANNE", "ANGELICA", + "JOHNNIE", "ROBYN", "FRANCIS", "ADRIENNE", "ROSALIE", "ALEXANDRA", "BROOKE", "BETHANY", "SADIE", "BERNADETTE", + "TRACI", "JODY", "KENDRA", "JASMINE", "NICHOLE", "RACHAEL", "CHELSEA", "MABLE", "ERNESTINE", "MURIEL", + "MARCELLA", "ELENA", "KRYSTAL", "ANGELINA", "NADINE", "KARI", "ESTELLE", "DIANNA", "PAULETTE", "LORA", + "MONA", "DOREEN", "ROSEMARIE", "ANGEL", "DESIREE", "ANTONIA", "HOPE", "GINGER", "JANIS", "BETSY", + "CHRISTIE", "FREDA", "MERCEDES", "MEREDITH", "LYNETTE", "TERI", "CRISTINA", "EULA", "LEIGH", "MEGHAN", + "SOPHIA", "ELOISE", "ROCHELLE", "GRETCHEN", "CECELIA", "RAQUEL", "HENRIETTA", "ALYSSA", "JANA", "KELLEY", + "GWEN", "KERRY", "JENNA", "TRICIA", "LAVERNE", "OLIVE", "ALEXIS", "TASHA", "SILVIA", "ELVIRA", + "CASEY", "DELIA", "SOPHIE", "KATE", "PATTI", "LORENA", "KELLIE", "SONJA", "LILA", "LANA", + "DARLA", "MAY", "MINDY", "ESSIE", "MANDY", "LORENE", "ELSA", "JOSEFINA", "JEANNIE", "MIRANDA", + "DIXIE", "LUCIA", "MARTA", "FAITH", "LELA", "JOHANNA", "SHARI", "CAMILLE", "TAMI", "SHAWNA", + "ELISA", "EBONY", "MELBA", "ORA", "NETTIE", "TABITHA", "OLLIE", "JAIME", "WINIFRED", "KRISTIE", + "MARINA", "ALISHA", "AIMEE", "RENA", "MYRNA", "MARLA", "TAMMIE", "LATASHA", "BONITA", "PATRICE", + "RONDA", "SHERRIE", "ADDIE", "FRANCINE", "DELORIS", "STACIE", "ADRIANA", "CHERI", "SHELBY", "ABIGAIL", + "CELESTE", "JEWEL", "CARA", "ADELE", "REBEKAH", "LUCINDA", "DORTHY", "CHRIS", "EFFIE", "TRINA", + "REBA", "SHAWN", "SALLIE", "AURORA", "LENORA", "ETTA", "LOTTIE", "KERRI", "TRISHA", "NIKKI", + "ESTELLA", "FRANCISCA", "JOSIE", "TRACIE", "MARISSA", "KARIN", "BRITTNEY", "JANELLE", "LOURDES", "LAUREL", + "HELENE", "FERN", "ELVA", "CORINNE", "KELSEY", "INA", "BETTIE", "ELISABETH", "AIDA", "CAITLIN", + "INGRID", "IVA", "EUGENIA", "CHRISTA", "GOLDIE", "CASSIE", "MAUDE", "JENIFER", "THERESE", "FRANKIE", + "DENA", "LORNA", "JANETTE", "LATONYA", "CANDY", "MORGAN", "CONSUELO", "TAMIKA", "ROSETTA", "DEBORA", + "CHERIE", "POLLY", "DINA", "JEWELL", "FAY", "JILLIAN", "DOROTHEA", "NELL", "TRUDY", "ESPERANZA", + "PATRICA", "KIMBERLEY", "SHANNA", "HELENA", "CAROLINA", "CLEO", "STEFANIE", "ROSARIO", "OLA", "JANINE", + "MOLLIE", "LUPE", "ALISA", "LOU", "MARIBEL", "SUSANNE", "BETTE", "SUSANA", "ELISE", "CECILE", + "ISABELLE", "LESLEY", "JOCELYN", "PAIGE", "JONI", "RACHELLE", "LEOLA", "DAPHNE", "ALTA", "ESTER", + "PETRA", "GRACIELA", "IMOGENE", "JOLENE", "KEISHA", "LACEY", "GLENNA", "GABRIELA", "KERI", "URSULA", + "LIZZIE", "KIRSTEN", "SHANA", "ADELINE", "MAYRA", "JAYNE", "JACLYN", "GRACIE", "SONDRA", "CARMELA", + "MARISA", "ROSALIND", "CHARITY", "TONIA", "BEATRIZ", "MARISOL", "CLARICE", "JEANINE", "SHEENA", "ANGELINE", + "FRIEDA", "LILY", "ROBBIE", "SHAUNA", "MILLIE", "CLAUDETTE", "CATHLEEN", "ANGELIA", "GABRIELLE", "AUTUMN", + "KATHARINE", "SUMMER", "JODIE", "STACI", "LEA", "CHRISTI", "JIMMIE", "JUSTINE", "ELMA", "LUELLA", + "MARGRET", "DOMINIQUE", "SOCORRO", "RENE", "MARTINA", "MARGO", "MAVIS", "CALLIE", "BOBBI", "MARITZA", + "LUCILE", "LEANNE", "JEANNINE", "DEANA", "AILEEN", "LORIE", "LADONNA", "WILLA", "MANUELA", "GALE", + "SELMA", "DOLLY", "SYBIL", "ABBY", "LARA", "DALE", "IVY", "DEE", "WINNIE", "MARCY", + "LUISA", "JERI", "MAGDALENA", "OFELIA", "MEAGAN", "AUDRA", "MATILDA", "LEILA", "CORNELIA", "BIANCA", + "SIMONE", "BETTYE", "RANDI", "VIRGIE", "LATISHA", "BARBRA", "GEORGINA", "ELIZA", "LEANN", "BRIDGETTE", + "RHODA", "HALEY", "ADELA", "NOLA", "BERNADINE", "FLOSSIE", "ILA", "GRETA", "RUTHIE", "NELDA", + "MINERVA", "LILLY", "TERRIE", "LETHA", "HILARY", "ESTELA", "VALARIE", "BRIANNA", "ROSALYN", "EARLINE", + "CATALINA", "AVA", "MIA", "CLARISSA", "LIDIA", "CORRINE", "ALEXANDRIA", "CONCEPCION", "TIA", "SHARRON", + "RAE", "DONA", "ERICKA", "JAMI", "ELNORA", "CHANDRA", "LENORE", "NEVA", "MARYLOU", "MELISA", + "TABATHA", "SERENA", "AVIS", "ALLIE", "SOFIA", "JEANIE", "ODESSA", "NANNIE", "HARRIETT", "LORAINE", + "PENELOPE", "MILAGROS", "EMILIA", "BENITA", "ALLYSON", "ASHLEE", "TANIA", "TOMMIE", "ESMERALDA", "KARINA", + "EVE", "PEARLIE", "ZELMA", "MALINDA", "NOREEN", "TAMEKA", "SAUNDRA", "HILLARY", "AMIE", "ALTHEA", + "ROSALINDA", "JORDAN", "LILIA", "ALANA", "GAY", "CLARE", "ALEJANDRA", "ELINOR", "MICHAEL", "LORRIE", + "JERRI", "DARCY", "EARNESTINE", "CARMELLA", "TAYLOR", "NOEMI", "MARCIE", "LIZA", "ANNABELLE", "LOUISA", + "EARLENE", "MALLORY", "CARLENE", "NITA", "SELENA", "TANISHA", "KATY", "JULIANNE", "JOHN", "LAKISHA", + "EDWINA", "MARICELA", "MARGERY", "KENYA", "DOLLIE", "ROXIE", "ROSLYN", "KATHRINE", "NANETTE", "CHARMAINE", + "LAVONNE", "ILENE", "KRIS", "TAMMI", "SUZETTE", "CORINE", "KAYE", "JERRY", "MERLE", "CHRYSTAL", + "LINA", "DEANNE", "LILIAN", "JULIANA", "ALINE", "LUANN", "KASEY", "MARYANNE", "EVANGELINE", "COLETTE", + "MELVA", "LAWANDA", "YESENIA", "NADIA", "MADGE", "KATHIE", "EDDIE", "OPHELIA", "VALERIA", "NONA", + "MITZI", "MARI", "GEORGETTE", "CLAUDINE", "FRAN", "ALISSA", "ROSEANN", "LAKEISHA", "SUSANNA", "REVA", + "DEIDRE", "CHASITY", "SHEREE", "CARLY", "JAMES", "ELVIA", "ALYCE", "DEIRDRE", "GENA", "BRIANA", + "ARACELI", "KATELYN", "ROSANNE", "WENDI", "TESSA", "BERTA", "MARVA", "IMELDA", "MARIETTA", "MARCI", + "LEONOR", "ARLINE", "SASHA", "MADELYN", "JANNA", "JULIETTE", "DEENA", "AURELIA", "JOSEFA", "AUGUSTA", + "LILIANA", "YOUNG", "CHRISTIAN", "LESSIE", "AMALIA", "SAVANNAH", "ANASTASIA", "VILMA", "NATALIA", "ROSELLA", + "LYNNETTE", "CORINA", "ALFREDA", "LEANNA", "CAREY", "AMPARO", "COLEEN", "TAMRA", "AISHA", "WILDA", + "KARYN", "CHERRY", "QUEEN", "MAURA", "MAI", "EVANGELINA", "ROSANNA", "HALLIE", "ERNA", "ENID", + "MARIANA", "LACY", "JULIET", "JACKLYN", "FREIDA", "MADELEINE", "MARA", "HESTER", "CATHRYN", "LELIA", + "CASANDRA", "BRIDGETT", "ANGELITA", "JANNIE", "DIONNE", "ANNMARIE", "KATINA", "BERYL", "PHOEBE", "MILLICENT", + "KATHERYN", "DIANN", "CARISSA", "MARYELLEN", "LIZ", "LAURI", "HELGA", "GILDA", "ADRIAN", "RHEA", + "MARQUITA", "HOLLIE", "TISHA", "TAMERA", "ANGELIQUE", "FRANCESCA", "BRITNEY", "KAITLIN", "LOLITA", "FLORINE", + "ROWENA", "REYNA", "TWILA", "FANNY", "JANELL", "INES", "CONCETTA", "BERTIE", "ALBA", "BRIGITTE", + "ALYSON", "VONDA", "PANSY", "ELBA", "NOELLE", "LETITIA", "KITTY", "DEANN", "BRANDIE", "LOUELLA", + "LETA", "FELECIA", "SHARLENE", "LESA", "BEVERLEY", "ROBERT", "ISABELLA", "HERMINIA", "TERRA", "CELINA", + "TORI", "OCTAVIA", "JADE", "DENICE", "GERMAINE", "SIERRA", "MICHELL", "CORTNEY", "NELLY", "DORETHA", + "SYDNEY", "DEIDRA", "MONIKA", "LASHONDA", "JUDI", "CHELSEY", "ANTIONETTE", "MARGOT", "BOBBY", "ADELAIDE", + "NAN", "LEEANN", "ELISHA", "DESSIE", "LIBBY", "KATHI", "GAYLA", "LATANYA", "MINA", "MELLISA", + "KIMBERLEE", "JASMIN", "RENAE", "ZELDA", "ELDA", "MA", "JUSTINA", "GUSSIE", "EMILIE", "CAMILLA", + "ABBIE", "ROCIO", "KAITLYN", "JESSE", "EDYTHE", "ASHLEIGH", "SELINA", "LAKESHA", "GERI", "ALLENE", + "PAMALA", "MICHAELA", "DAYNA", "CARYN", "ROSALIA", "SUN", "JACQULINE", "REBECA", "MARYBETH", "KRYSTLE", + "IOLA", "DOTTIE", "BENNIE", "BELLE", "AUBREY", "GRISELDA", "ERNESTINA", "ELIDA", "ADRIANNE", "DEMETRIA", + "DELMA", "CHONG", "JAQUELINE", "DESTINY", "ARLEEN", "VIRGINA", "RETHA", "FATIMA", "TILLIE", "ELEANORE", + "CARI", "TREVA", "BIRDIE", "WILHELMINA", "ROSALEE", "MAURINE", "LATRICE", "YONG", "JENA", "TARYN", + "ELIA", "DEBBY", "MAUDIE", "JEANNA", "DELILAH", "CATRINA", "SHONDA", "HORTENCIA", "THEODORA", "TERESITA", + "ROBBIN", "DANETTE", "MARYJANE", "FREDDIE", "DELPHINE", "BRIANNE", "NILDA", "DANNA", "CINDI", "BESS", + "IONA", "HANNA", "ARIEL", "WINONA", "VIDA", "ROSITA", "MARIANNA", "WILLIAM", "RACHEAL", "GUILLERMINA", + "ELOISA", "CELESTINE", "CAREN", "MALISSA", "LONA", "CHANTEL", "SHELLIE", "MARISELA", "LEORA", "AGATHA", + "SOLEDAD", "MIGDALIA", "IVETTE", "CHRISTEN", "ATHENA", "JANEL", "CHLOE", "VEDA", "PATTIE", "TESSIE", + "TERA", "MARILYNN", "LUCRETIA", "KARRIE", "DINAH", "DANIELA", "ALECIA", "ADELINA", "VERNICE", "SHIELA", + "PORTIA", "MERRY", "LASHAWN", "DEVON", "DARA", "TAWANA", "OMA", "VERDA", "CHRISTIN", "ALENE", + "ZELLA", "SANDI", "RAFAELA", "MAYA", "KIRA", "CANDIDA", "ALVINA", "SUZAN", "SHAYLA", "LYN", + "LETTIE", "ALVA", "SAMATHA", "ORALIA", "MATILDE", "MADONNA", "LARISSA", "VESTA", "RENITA", "INDIA", + "DELOIS", "SHANDA", "PHILLIS", "LORRI", "ERLINDA", "CRUZ", "CATHRINE", "BARB", "ZOE", "ISABELL", + "IONE", "GISELA", "CHARLIE", "VALENCIA", "ROXANNA", "MAYME", "KISHA", "ELLIE", "MELLISSA", "DORRIS", + "DALIA", "BELLA", "ANNETTA", "ZOILA", "RETA", "REINA", "LAURETTA", "KYLIE", "CHRISTAL", "PILAR", + "CHARLA", "ELISSA", "TIFFANI", "TANA", "PAULINA", "LEOTA", "BREANNA", "JAYME", "CARMEL", "VERNELL", + "TOMASA", "MANDI", "DOMINGA", "SANTA", "MELODIE", "LURA", "ALEXA", "TAMELA", "RYAN", "MIRNA", + "KERRIE", "VENUS", "NOEL", "FELICITA", "CRISTY", "CARMELITA", "BERNIECE", "ANNEMARIE", "TIARA", "ROSEANNE", + "MISSY", "CORI", "ROXANA", "PRICILLA", "KRISTAL", "JUNG", "ELYSE", "HAYDEE", "ALETHA", "BETTINA", + "MARGE", "GILLIAN", "FILOMENA", "CHARLES", "ZENAIDA", "HARRIETTE", "CARIDAD", "VADA", "UNA", "ARETHA", + "PEARLINE", "MARJORY", "MARCELA", "FLOR", "EVETTE", "ELOUISE", "ALINA", "TRINIDAD", "DAVID", "DAMARIS", + "CATHARINE", "CARROLL", "BELVA", "NAKIA", "MARLENA", "LUANNE", "LORINE", "KARON", "DORENE", "DANITA", + "BRENNA", "TATIANA", "SAMMIE", "LOUANN", "LOREN", "JULIANNA", "ANDRIA", "PHILOMENA", "LUCILA", "LEONORA", + "DOVIE", "ROMONA", "MIMI", "JACQUELIN", "GAYE", "TONJA", "MISTI", "JOE", "GENE", "CHASTITY", + "STACIA", "ROXANN", "MICAELA", "NIKITA", "MEI", "VELDA", "MARLYS", "JOHNNA", "AURA", "LAVERN", + "IVONNE", "HAYLEY", "NICKI", "MAJORIE", "HERLINDA", "GEORGE", "ALPHA", "YADIRA", "PERLA", "GREGORIA", + "DANIEL", "ANTONETTE", "SHELLI", "MOZELLE", "MARIAH", "JOELLE", "CORDELIA", "JOSETTE", "CHIQUITA", "TRISTA", + "LOUIS", "LAQUITA", "GEORGIANA", "CANDI", "SHANON", "LONNIE", "HILDEGARD", "CECIL", "VALENTINA", "STEPHANY", + "MAGDA", "KAROL", "GERRY", "GABRIELLA", "TIANA", "ROMA", "RICHELLE", "RAY", "PRINCESS", "OLETA", + "JACQUE", "IDELLA", "ALAINA", "SUZANNA", "JOVITA", "BLAIR", "TOSHA", "RAVEN", "NEREIDA", "MARLYN", + "KYLA", "JOSEPH", "DELFINA", "TENA", "STEPHENIE", "SABINA", "NATHALIE", "MARCELLE", "GERTIE", "DARLEEN", + "THEA", "SHARONDA", "SHANTEL", "BELEN", "VENESSA", "ROSALINA", "ONA", "GENOVEVA", "COREY", "CLEMENTINE", + "ROSALBA", "RENATE", "RENATA", "MI", "IVORY", "GEORGIANNA", "FLOY", "DORCAS", "ARIANA", "TYRA", + "THEDA", "MARIAM", "JULI", "JESICA", "DONNIE", "VIKKI", "VERLA", "ROSELYN", "MELVINA", "JANNETTE", + "GINNY", "DEBRAH", "CORRIE", "ASIA", "VIOLETA", "MYRTIS", "LATRICIA", "COLLETTE", "CHARLEEN", "ANISSA", + "VIVIANA", "TWYLA", "PRECIOUS", "NEDRA", "LATONIA", "LAN", "HELLEN", "FABIOLA", "ANNAMARIE", "ADELL", + "SHARYN", "CHANTAL", "NIKI", "MAUD", "LIZETTE", "LINDY", "KIA", "KESHA", "JEANA", "DANELLE", + "CHARLINE", "CHANEL", "CARROL", "VALORIE", "LIA", "DORTHA", "CRISTAL", "SUNNY", "LEONE", "LEILANI", + "GERRI", "DEBI", "ANDRA", "KESHIA", "IMA", "EULALIA", "EASTER", "DULCE", "NATIVIDAD", "LINNIE", + "KAMI", "GEORGIE", "CATINA", "BROOK", "ALDA", "WINNIFRED", "SHARLA", "RUTHANN", "MEAGHAN", "MAGDALENE", + "LISSETTE", "ADELAIDA", "VENITA", "TRENA", "SHIRLENE", "SHAMEKA", "ELIZEBETH", "DIAN", "SHANTA", "MICKEY", + "LATOSHA", "CARLOTTA", "WINDY", "SOON", "ROSINA", "MARIANN", "LEISA", "JONNIE", "DAWNA", "CATHIE", + "BILLY", "ASTRID", "SIDNEY", "LAUREEN", "JANEEN", "HOLLI", "FAWN", "VICKEY", "TERESSA", "SHANTE", + "RUBYE", "MARCELINA", "CHANDA", "CARY", "TERESE", "SCARLETT", "MARTY", "MARNIE", "LULU", "LISETTE", + "JENIFFER", "ELENOR", "DORINDA", "DONITA", "CARMAN", "BERNITA", "ALTAGRACIA", "ALETA", "ADRIANNA", "ZORAIDA", + "RONNIE", "NICOLA", "LYNDSEY", "KENDALL", "JANINA", "CHRISSY", "AMI", "STARLA", "PHYLIS", "PHUONG", + "KYRA", "CHARISSE", "BLANCH", "SANJUANITA", "RONA", "NANCI", "MARILEE", "MARANDA", "CORY", "BRIGETTE", + "SANJUANA", "MARITA", "KASSANDRA", "JOYCELYN", "IRA", "FELIPA", "CHELSIE", "BONNY", "MIREYA", "LORENZA", + "KYONG", "ILEANA", "CANDELARIA", "TONY", "TOBY", "SHERIE", "OK", "MARK", "LUCIE", "LEATRICE", + "LAKESHIA", "GERDA", "EDIE", "BAMBI", "MARYLIN", "LAVON", "HORTENSE", "GARNET", "EVIE", "TRESSA", + "SHAYNA", "LAVINA", "KYUNG", "JEANETTA", "SHERRILL", "SHARA", "PHYLISS", "MITTIE", "ANABEL", "ALESIA", + "THUY", "TAWANDA", "RICHARD", "JOANIE", "TIFFANIE", "LASHANDA", "KARISSA", "ENRIQUETA", "DARIA", "DANIELLA", + "CORINNA", "ALANNA", "ABBEY", "ROXANE", "ROSEANNA", "MAGNOLIA", "LIDA", "KYLE", "JOELLEN", "ERA", + "CORAL", "CARLEEN", "TRESA", "PEGGIE", "NOVELLA", "NILA", "MAYBELLE", "JENELLE", "CARINA", "NOVA", + "MELINA", "MARQUERITE", "MARGARETTE", "JOSEPHINA", "EVONNE", "DEVIN", "CINTHIA", "ALBINA", "TOYA", "TAWNYA", + "SHERITA", "SANTOS", "MYRIAM", "LIZABETH", "LISE", "KEELY", "JENNI", "GISELLE", "CHERYLE", "ARDITH", + "ARDIS", "ALESHA", "ADRIANE", "SHAINA", "LINNEA", "KAROLYN", "HONG", "FLORIDA", "FELISHA", "DORI", + "DARCI", "ARTIE", "ARMIDA", "ZOLA", "XIOMARA", "VERGIE", "SHAMIKA", "NENA", "NANNETTE", "MAXIE", + "LOVIE", "JEANE", "JAIMIE", "INGE", "FARRAH", "ELAINA", "CAITLYN", "STARR", "FELICITAS", "CHERLY", + "CARYL", "YOLONDA", "YASMIN", "TEENA", "PRUDENCE", "PENNIE", "NYDIA", "MACKENZIE", "ORPHA", "MARVEL", + "LIZBETH", "LAURETTE", "JERRIE", "HERMELINDA", "CAROLEE", "TIERRA", "MIRIAN", "META", "MELONY", "KORI", + "JENNETTE", "JAMILA", "ENA", "ANH", "YOSHIKO", "SUSANNAH", "SALINA", "RHIANNON", "JOLEEN", "CRISTINE", + "ASHTON", "ARACELY", "TOMEKA", "SHALONDA", "MARTI", "LACIE", "KALA", "JADA", "ILSE", "HAILEY", + "BRITTANI", "ZONA", "SYBLE", "SHERRYL", "RANDY", "NIDIA", "MARLO", "KANDICE", "KANDI", "DEB", + "DEAN", "AMERICA", "ALYCIA", "TOMMY", "RONNA", "NORENE", "MERCY", "JOSE", "INGEBORG", "GIOVANNA", + "GEMMA", "CHRISTEL", "AUDRY", "ZORA", "VITA", "VAN", "TRISH", "STEPHAINE", "SHIRLEE", "SHANIKA", + "MELONIE", "MAZIE", "JAZMIN", "INGA", "HOA", "HETTIE", "GERALYN", "FONDA", "ESTRELLA", "ADELLA", + "SU", "SARITA", "RINA", "MILISSA", "MARIBETH", "GOLDA", "EVON", "ETHELYN", "ENEDINA", "CHERISE", + "CHANA", "VELVA", "TAWANNA", "SADE", "MIRTA", "LI", "KARIE", "JACINTA", "ELNA", "DAVINA", + "CIERRA", "ASHLIE", "ALBERTHA", "TANESHA", "STEPHANI", "NELLE", "MINDI", "LU", "LORINDA", "LARUE", + "FLORENE", "DEMETRA", "DEDRA", "CIARA", "CHANTELLE", "ASHLY", "SUZY", "ROSALVA", "NOELIA", "LYDA", + "LEATHA", "KRYSTYNA", "KRISTAN", "KARRI", "DARLINE", "DARCIE", "CINDA", "CHEYENNE", "CHERRIE", "AWILDA", + "ALMEDA", "ROLANDA", "LANETTE", "JERILYN", "GISELE", "EVALYN", "CYNDI", "CLETA", "CARIN", "ZINA", + "ZENA", "VELIA", "TANIKA", "PAUL", "CHARISSA", "THOMAS", "TALIA", "MARGARETE", "LAVONDA", "KAYLEE", + "KATHLENE", "JONNA", "IRENA", "ILONA", "IDALIA", "CANDIS", "CANDANCE", "BRANDEE", "ANITRA", "ALIDA", + "SIGRID", "NICOLETTE", "MARYJO", "LINETTE", "HEDWIG", "CHRISTIANA", "CASSIDY", "ALEXIA", "TRESSIE", "MODESTA", + "LUPITA", "LITA", "GLADIS", "EVELIA", "DAVIDA", "CHERRI", "CECILY", "ASHELY", "ANNABEL", "AGUSTINA", + "WANITA", "SHIRLY", "ROSAURA", "HULDA", "EUN", "BAILEY", "YETTA", "VERONA", "THOMASINA", "SIBYL", + "SHANNAN", "MECHELLE", "LUE", "LEANDRA", "LANI", "KYLEE", "KANDY", "JOLYNN", "FERNE", "EBONI", + "CORENE", "ALYSIA", "ZULA", "NADA", "MOIRA", "LYNDSAY", "LORRETTA", "JUAN", "JAMMIE", "HORTENSIA", + "GAYNELL", "CAMERON", "ADRIA", "VINA", "VICENTA", "TANGELA", "STEPHINE", "NORINE", "NELLA", "LIANA", + "LESLEE", "KIMBERELY", "ILIANA", "GLORY", "FELICA", "EMOGENE", "ELFRIEDE", "EDEN", "EARTHA", "CARMA", + "BEA", "OCIE", "MARRY", "LENNIE", "KIARA", "JACALYN", "CARLOTA", "ARIELLE", "YU", "STAR", + "OTILIA", "KIRSTIN", "KACEY", "JOHNETTA", "JOEY", "JOETTA", "JERALDINE", "JAUNITA", "ELANA", "DORTHEA", + "CAMI", "AMADA", "ADELIA", "VERNITA", "TAMAR", "SIOBHAN", "RENEA", "RASHIDA", "OUIDA", "ODELL", + "NILSA", "MERYL", "KRISTYN", "JULIETA", "DANICA", "BREANNE", "AUREA", "ANGLEA", "SHERRON", "ODETTE", + "MALIA", "LORELEI", "LIN", "LEESA", "KENNA", "KATHLYN", "FIONA", "CHARLETTE", "SUZIE", "SHANTELL", + "SABRA", "RACQUEL", "MYONG", "MIRA", "MARTINE", "LUCIENNE", "LAVADA", "JULIANN", "JOHNIE", "ELVERA", + "DELPHIA", "CLAIR", "CHRISTIANE", "CHAROLETTE", "CARRI", "AUGUSTINE", "ASHA", "ANGELLA", "PAOLA", "NINFA", + "LEDA", "LAI", "EDA", "SUNSHINE", "STEFANI", "SHANELL", "PALMA", "MACHELLE", "LISSA", "KECIA", + "KATHRYNE", "KARLENE", "JULISSA", "JETTIE", "JENNIFFER", "HUI", "CORRINA", "CHRISTOPHER", "CAROLANN", "ALENA", + "TESS", "ROSARIA", "MYRTICE", "MARYLEE", "LIANE", "KENYATTA", "JUDIE", "JANEY", "IN", "ELMIRA", + "ELDORA", "DENNA", "CRISTI", "CATHI", "ZAIDA", "VONNIE", "VIVA", "VERNIE", "ROSALINE", "MARIELA", + "LUCIANA", "LESLI", "KARAN", "FELICE", "DENEEN", "ADINA", "WYNONA", "TARSHA", "SHERON", "SHASTA", + "SHANITA", "SHANI", "SHANDRA", "RANDA", "PINKIE", "PARIS", "NELIDA", "MARILOU", "LYLA", "LAURENE", + "LACI", "JOI", "JANENE", "DOROTHA", "DANIELE", "DANI", "CAROLYNN", "CARLYN", "BERENICE", "AYESHA", + "ANNELIESE", "ALETHEA", "THERSA", "TAMIKO", "RUFINA", "OLIVA", "MOZELL", "MARYLYN", "MADISON", "KRISTIAN", + "KATHYRN", "KASANDRA", "KANDACE", "JANAE", "GABRIEL", "DOMENICA", "DEBBRA", "DANNIELLE", "CHUN", "BUFFY", + "BARBIE", "ARCELIA", "AJA", "ZENOBIA", "SHAREN", "SHAREE", "PATRICK", "PAGE", "MY", "LAVINIA", + "KUM", "KACIE", "JACKELINE", "HUONG", "FELISA", "EMELIA", "ELEANORA", "CYTHIA", "CRISTIN", "CLYDE", + "CLARIBEL", "CARON", "ANASTACIA", "ZULMA", "ZANDRA", "YOKO", "TENISHA", "SUSANN", "SHERILYN", "SHAY", + "SHAWANDA", "SABINE", "ROMANA", "MATHILDA", "LINSEY", "KEIKO", "JOANA", "ISELA", "GRETTA", "GEORGETTA", + "EUGENIE", "DUSTY", "DESIRAE", "DELORA", "CORAZON", "ANTONINA", "ANIKA", "WILLENE", "TRACEE", "TAMATHA", + "REGAN", "NICHELLE", "MICKIE", "MAEGAN", "LUANA", "LANITA", "KELSIE", "EDELMIRA", "BREE", "AFTON", + "TEODORA", "TAMIE", "SHENA", "MEG", "LINH", "KELI", "KACI", "DANYELLE", "BRITT", "ARLETTE", + "ALBERTINE", "ADELLE", "TIFFINY", "STORMY", "SIMONA", "NUMBERS", "NICOLASA", "NICHOL", "NIA", "NAKISHA", + "MEE", "MAIRA", "LOREEN", "KIZZY", "JOHNNY", "JAY", "FALLON", "CHRISTENE", "BOBBYE", "ANTHONY", + "YING", "VINCENZA", "TANJA", "RUBIE", "RONI", "QUEENIE", "MARGARETT", "KIMBERLI", "IRMGARD", "IDELL", + "HILMA", "EVELINA", "ESTA", "EMILEE", "DENNISE", "DANIA", "CARL", "CARIE", "ANTONIO", "WAI", + "SANG", "RISA", "RIKKI", "PARTICIA", "MUI", "MASAKO", "MARIO", "LUVENIA", "LOREE", "LONI", + "LIEN", "KEVIN", "GIGI", "FLORENCIA", "DORIAN", "DENITA", "DALLAS", "CHI", "BILLYE", "ALEXANDER", + "TOMIKA", "SHARITA", "RANA", "NIKOLE", "NEOMA", "MARGARITE", "MADALYN", "LUCINA", "LAILA", "KALI", + "JENETTE", "GABRIELE", "EVELYNE", "ELENORA", "CLEMENTINA", "ALEJANDRINA", "ZULEMA", "VIOLETTE", "VANNESSA", "THRESA", + "RETTA", "PIA", "PATIENCE", "NOELLA", "NICKIE", "JONELL", "DELTA", "CHUNG", "CHAYA", "CAMELIA", + "BETHEL", "ANYA", "ANDREW", "THANH", "SUZANN", "SPRING", "SHU", "MILA", "LILLA", "LAVERNA", + "KEESHA", "KATTIE", "GIA", "GEORGENE", "EVELINE", "ESTELL", "ELIZBETH", "VIVIENNE", "VALLIE", "TRUDIE", + "STEPHANE", "MICHEL", "MAGALY", "MADIE", "KENYETTA", "KARREN", "JANETTA", "HERMINE", "HARMONY", "DRUCILLA", + "DEBBI", "CELESTINA", "CANDIE", "BRITNI", "BECKIE", "AMINA", "ZITA", "YUN", "YOLANDE", "VIVIEN", + "VERNETTA", "TRUDI", "SOMMER", "PEARLE", "PATRINA", "OSSIE", "NICOLLE", "LOYCE", "LETTY", "LARISA", + "KATHARINA", "JOSELYN", "JONELLE", "JENELL", "IESHA", "HEIDE", "FLORINDA", "FLORENTINA", "FLO", "ELODIA", + "DORINE", "BRUNILDA", "BRIGID", "ASHLI", "ARDELLA", "TWANA", "THU", "TARAH", "SUNG", "SHEA", + "SHAVON", "SHANE", "SERINA", "RAYNA", "RAMONITA", "NGA", "MARGURITE", "LUCRECIA", "KOURTNEY", "KATI", + "JESUS", "JESENIA", "DIAMOND", "CRISTA", "AYANA", "ALICA", "ALIA", "VINNIE", "SUELLEN", "ROMELIA", + "RACHELL", "PIPER", "OLYMPIA", "MICHIKO", "KATHALEEN", "JOLIE", "JESSI", "JANESSA", "HANA", "HA", + "ELEASE", "CARLETTA", "BRITANY", "SHONA", "SALOME", "ROSAMOND", "REGENA", "RAINA", "NGOC", "NELIA", + "LOUVENIA", "LESIA", "LATRINA", "LATICIA", "LARHONDA", "JINA", "JACKI", "HOLLIS", "HOLLEY", "EMMY", + "DEEANN", "CORETTA", "ARNETTA", "VELVET", "THALIA", "SHANICE", "NETA", "MIKKI", "MICKI", "LONNA", + "LEANA", "LASHUNDA", "KILEY", "JOYE", "JACQULYN", "IGNACIA", "HYUN", "HIROKO", "HENRY", "HENRIETTE", + "ELAYNE", "DELINDA", "DARNELL", "DAHLIA", "COREEN", "CONSUELA", "CONCHITA", "CELINE", "BABETTE", "AYANNA", + "ANETTE", "ALBERTINA", "SKYE", "SHAWNEE", "SHANEKA", "QUIANA", "PAMELIA", "MIN", "MERRI", "MERLENE", + "MARGIT", "KIESHA", "KIERA", "KAYLENE", "JODEE", "JENISE", "ERLENE", "EMMIE", "ELSE", "DARYL", + "DALILA", "DAISEY", "CODY", "CASIE", "BELIA", "BABARA", "VERSIE", "VANESA", "SHELBA", "SHAWNDA", + "SAM", "NORMAN", "NIKIA", "NAOMA", "MARNA", "MARGERET", "MADALINE", "LAWANA", "KINDRA", "JUTTA", + "JAZMINE", "JANETT", "HANNELORE", "GLENDORA", "GERTRUD", "GARNETT", "FREEDA", "FREDERICA", "FLORANCE", "FLAVIA", + "DENNIS", "CARLINE", "BEVERLEE", "ANJANETTE", "VALDA", "TRINITY", "TAMALA", "STEVIE", "SHONNA", "SHA", + "SARINA", "ONEIDA", "MICAH", "MERILYN", "MARLEEN", "LURLINE", "LENNA", "KATHERIN", "JIN", "JENI", + "HAE", "GRACIA", "GLADY", "FARAH", "ERIC", "ENOLA", "EMA", "DOMINQUE", "DEVONA", "DELANA", + "CECILA", "CAPRICE", "ALYSHA", "ALI", "ALETHIA", "VENA", "THERESIA", "TAWNY", "SONG", "SHAKIRA", + "SAMARA", "SACHIKO", "RACHELE", "PAMELLA", "NICKY", "MARNI", "MARIEL", "MAREN", "MALISA", "LIGIA", + "LERA", "LATORIA", "LARAE", "KIMBER", "KATHERN", "KAREY", "JENNEFER", "JANETH", "HALINA", "FREDIA", + "DELISA", "DEBROAH", "CIERA", "CHIN", "ANGELIKA", "ANDREE", "ALTHA", "YEN", "VIVAN", "TERRESA", + "TANNA", "SUK", "SUDIE", "SOO", "SIGNE", "SALENA", "RONNI", "REBBECCA", "MYRTIE", "MCKENZIE", + "MALIKA", "MAIDA", "LOAN", "LEONARDA", "KAYLEIGH", "FRANCE", "ETHYL", "ELLYN", "DAYLE", "CAMMIE", + "BRITTNI", "BIRGIT", "AVELINA", "ASUNCION", "ARIANNA", "AKIKO", "VENICE", "TYESHA", "TONIE", "TIESHA", + "TAKISHA", "STEFFANIE", "SINDY", "SANTANA", "MEGHANN", "MANDA", "MACIE", "LADY", "KELLYE", "KELLEE", + "JOSLYN", "JASON", "INGER", "INDIRA", "GLINDA", "GLENNIS", "FERNANDA", "FAUSTINA", "ENEIDA", "ELICIA", + "DOT", "DIGNA", "DELL", "ARLETTA", "ANDRE", "WILLIA", "TAMMARA", "TABETHA", "SHERRELL", "SARI", + "REFUGIO", "REBBECA", "PAULETTA", "NIEVES", "NATOSHA", "NAKITA", "MAMMIE", "KENISHA", "KAZUKO", "KASSIE", + "GARY", "EARLEAN", "DAPHINE", "CORLISS", "CLOTILDE", "CAROLYNE", "BERNETTA", "AUGUSTINA", "AUDREA", "ANNIS", + "ANNABELL", "YAN", "TENNILLE", "TAMICA", "SELENE", "SEAN", "ROSANA", "REGENIA", "QIANA", "MARKITA", + "MACY", "LEEANNE", "LAURINE", "KYM", "JESSENIA", "JANITA", "GEORGINE", "GENIE", "EMIKO", "ELVIE", + "DEANDRA", "DAGMAR", "CORIE", "COLLEN", "CHERISH", "ROMAINE", "PORSHA", "PEARLENE", "MICHELINE", "MERNA", + "MARGORIE", "MARGARETTA", "LORE", "KENNETH", "JENINE", "HERMINA", "FREDERICKA", "ELKE", "DRUSILLA", "DORATHY", + "DIONE", "DESIRE", "CELENA", "BRIGIDA", "ANGELES", "ALLEGRA", "THEO", "TAMEKIA", "SYNTHIA", "STEPHEN", + "SOOK", "SLYVIA", "ROSANN", "REATHA", "RAYE", "MARQUETTA", "MARGART", "LING", "LAYLA", "KYMBERLY", + "KIANA", "KAYLEEN", "KATLYN", "KARMEN", "JOELLA", "IRINA", "EMELDA", "ELENI", "DETRA", "CLEMMIE", + "CHERYLL", "CHANTELL", "CATHEY", "ARNITA", "ARLA", "ANGLE", "ANGELIC", "ALYSE", "ZOFIA", "THOMASINE", + "TENNIE", "SON", "SHERLY", "SHERLEY", "SHARYL", "REMEDIOS", "PETRINA", "NICKOLE", "MYUNG", "MYRLE", + "MOZELLA", "LOUANNE", "LISHA", "LATIA", "LANE", "KRYSTA", "JULIENNE", "JOEL", "JEANENE", "JACQUALINE", + "ISAURA", "GWENDA", "EARLEEN", "DONALD", "CLEOPATRA", "CARLIE", "AUDIE", "ANTONIETTA", "ALISE", "ALEX", + "VERDELL", "VAL", "TYLER", "TOMOKO", "THAO", "TALISHA", "STEVEN", "SO", "SHEMIKA", "SHAUN", + "SCARLET", "SAVANNA", "SANTINA", "ROSIA", "RAEANN", "ODILIA", "NANA", "MINNA", "MAGAN", "LYNELLE", + "LE", "KARMA", "JOEANN", "IVANA", "INELL", "ILANA", "HYE", "HONEY", "HEE", "GUDRUN", + "FRANK", "DREAMA", "CRISSY", "CHANTE", "CARMELINA", "ARVILLA", "ARTHUR", "ANNAMAE", "ALVERA", "ALEIDA", + "AARON", "YEE", "YANIRA", "VANDA", "TIANNA", "TAM", "STEFANIA", "SHIRA", "PERRY", "NICOL", + "NANCIE", "MONSERRATE", "MINH", "MELYNDA", "MELANY", "MATTHEW", "LOVELLA", "LAURE", "KIRBY", "KACY", + "JACQUELYNN", "HYON", "GERTHA", "FRANCISCO", "ELIANA", "CHRISTENA", "CHRISTEEN", "CHARISE", "CATERINA", "CARLEY", + "CANDYCE", "ARLENA", "AMMIE", "YANG", "WILLETTE", "VANITA", "TUYET", "TINY", "SYREETA", "SILVA", + "SCOTT", "RONALD", "PENNEY", "NYLA", "MICHAL", "MAURICE", "MARYAM", "MARYA", "MAGEN", "LUDIE", + "LOMA", "LIVIA", "LANELL", "KIMBERLIE", "JULEE", "DONETTA", "DIEDRA", "DENISHA", "DEANE", "DAWNE", + "CLARINE", "CHERRYL", "BRONWYN", "BRANDON", "ALLA", "VALERY", "TONDA", "SUEANN", "SORAYA", "SHOSHANA", + "SHELA", "SHARLEEN", "SHANELLE", "NERISSA", "MICHEAL", "MERIDITH", "MELLIE", "MAYE", "MAPLE", "MAGARET", + "LUIS", "LILI", "LEONILA", "LEONIE", "LEEANNA", "LAVONIA", "LAVERA", "KRISTEL", "KATHEY", "KATHE", + "JUSTIN", "JULIAN", "JIMMY", "JANN", "ILDA", "HILDRED", "HILDEGARDE", "GENIA", "FUMIKO", "EVELIN", + "ERMELINDA", "ELLY", "DUNG", "DOLORIS", "DIONNA", "DANAE", "BERNEICE", "ANNICE", "ALIX", "VERENA", + "VERDIE", "TRISTAN", "SHAWNNA", "SHAWANA", "SHAUNNA", "ROZELLA", "RANDEE", "RANAE", "MILAGRO", "LYNELL", + "LUISE", "LOUIE", "LOIDA", "LISBETH", "KARLEEN", "JUNITA", "JONA", "ISIS", "HYACINTH", "HEDY", + "GWENN", "ETHELENE", "ERLINE", "EDWARD", "DONYA", "DOMONIQUE", "DELICIA", "DANNETTE", "CICELY", "BRANDA", + "BLYTHE", "BETHANN", "ASHLYN", "ANNALEE", "ALLINE", "YUKO", "VELLA", "TRANG", "TOWANDA", "TESHA", + "SHERLYN", "NARCISA", "MIGUELINA", "MERI", "MAYBELL", "MARLANA", "MARGUERITA", "MADLYN", "LUNA", "LORY", + "LORIANN", "LIBERTY", "LEONORE", "LEIGHANN", "LAURICE", "LATESHA", "LARONDA", "KATRICE", "KASIE", "KARL", + "KALEY", "JADWIGA", "GLENNIE", "GEARLDINE", "FRANCINA", "EPIFANIA", "DYAN", "DORIE", "DIEDRE", "DENESE", + "DEMETRICE", "DELENA", "DARBY", "CRISTIE", "CLEORA", "CATARINA", "CARISA", "BERNIE", "BARBERA", "ALMETA", + "TRULA", "TEREASA", "SOLANGE", "SHEILAH", "SHAVONNE", "SANORA", "ROCHELL", "MATHILDE", "MARGARETA", "MAIA", + "LYNSEY", "LAWANNA", "LAUNA", "KENA", "KEENA", "KATIA", "JAMEY", "GLYNDA", "GAYLENE", "ELVINA", + "ELANOR", "DANUTA", "DANIKA", "CRISTEN", "CORDIE", "COLETTA", "CLARITA", "CARMON", "BRYNN", "AZUCENA", + "AUNDREA", "ANGELE", "YI", "WALTER", "VERLIE", "VERLENE", "TAMESHA", "SILVANA", "SEBRINA", "SAMIRA", + "REDA", "RAYLENE", "PENNI", "PANDORA", "NORAH", "NOMA", "MIREILLE", "MELISSIA", "MARYALICE", "LARAINE", + "KIMBERY", "KARYL", "KARINE", "KAM", "JOLANDA", "JOHANA", "JESUSA", "JALEESA", "JAE", "JACQUELYNE", + "IRISH", "ILUMINADA", "HILARIA", "HANH", "GENNIE", "FRANCIE", "FLORETTA", "EXIE", "EDDA", "DREMA", + "DELPHA", "BEV", "BARBAR", "ASSUNTA", "ARDELL", "ANNALISA", "ALISIA", "YUKIKO", "YOLANDO", "WONDA", + "WEI", "WALTRAUD", "VETA", "TEQUILA", "TEMEKA", "TAMEIKA", "SHIRLEEN", "SHENITA", "PIEDAD", "OZELLA", + "MIRTHA", "MARILU", "KIMIKO", "JULIANE", "JENICE", "JEN", "JANAY", "JACQUILINE", "HILDE", "FE", + "FAE", "EVAN", "EUGENE", "ELOIS", "ECHO", "DEVORAH", "CHAU", "BRINDA", "BETSEY", "ARMINDA", + "ARACELIS", "APRYL", "ANNETT", "ALISHIA", "VEOLA", "USHA", "TOSHIKO", "THEOLA", "TASHIA", "TALITHA", + "SHERY", "RUDY", "RENETTA", "REIKO", "RASHEEDA", "OMEGA", "OBDULIA", "MIKA", "MELAINE", "MEGGAN", + "MARTIN", "MARLEN", "MARGET", "MARCELINE", "MANA", "MAGDALEN", "LIBRADA", "LEZLIE", "LEXIE", "LATASHIA", + "LASANDRA", "KELLE", "ISIDRA", "ISA", "INOCENCIA", "GWYN", "FRANCOISE", "ERMINIA", "ERINN", "DIMPLE", + "DEVORA", "CRISELDA", "ARMANDA", "ARIE", "ARIANE", "ANGELO", "ANGELENA", "ALLEN", "ALIZA", "ADRIENE", + "ADALINE", "XOCHITL", "TWANNA", "TRAN", "TOMIKO", "TAMISHA", "TAISHA", "SUSY", "SIU", "RUTHA", + "ROXY", "RHONA", "RAYMOND", "OTHA", "NORIKO", "NATASHIA", "MERRIE", "MELVIN", "MARINDA", "MARIKO", + "MARGERT", "LORIS", "LIZZETTE", "LEISHA", "KAILA", "KA", "JOANNIE", "JERRICA", "JENE", "JANNET", + "JANEE", "JACINDA", "HERTA", "ELENORE", "DORETTA", "DELAINE", "DANIELL", "CLAUDIE", "CHINA", "BRITTA", + "APOLONIA", "AMBERLY", "ALEASE", "YURI", "YUK", "WEN", "WANETA", "UTE", "TOMI", "SHARRI", + "SANDIE", "ROSELLE", "REYNALDA", "RAGUEL", "PHYLICIA", "PATRIA", "OLIMPIA", "ODELIA", "MITZIE", "MITCHELL", + "MISS", "MINDA", "MIGNON", "MICA", "MENDY", "MARIVEL", "MAILE", "LYNETTA", "LAVETTE", "LAURYN", + "LATRISHA", "LAKIESHA", "KIERSTEN", "KARY", "JOSPHINE", "JOLYN", "JETTA", "JANISE", "JACQUIE", "IVELISSE", + "GLYNIS", "GIANNA", "GAYNELLE", "EMERALD", "DEMETRIUS", "DANYELL", "DANILLE", "DACIA", "CORALEE", "CHER", + "CEOLA", "BRETT", "BELL", "ARIANNE", "ALESHIA", "YUNG", "WILLIEMAE", "TROY", "TRINH", "THORA", + "TAI", "SVETLANA", "SHERIKA", "SHEMEKA", "SHAUNDA", "ROSELINE", "RICKI", "MELDA", "MALLIE", "LAVONNA", + "LATINA", "LARRY", "LAQUANDA", "LALA", "LACHELLE", "KLARA", "KANDIS", "JOHNA", "JEANMARIE", "JAYE", + "HANG", "GRAYCE", "GERTUDE", "EMERITA", "EBONIE", "CLORINDA", "CHING", "CHERY", "CAROLA", "BREANN", + "BLOSSOM", "BERNARDINE", "BECKI", "ARLETHA", "ARGELIA", "ARA", "ALITA", "YULANDA", "YON", "YESSENIA", + "TOBI", "TASIA", "SYLVIE", "SHIRL", "SHIRELY", "SHERIDAN", "SHELLA", "SHANTELLE", "SACHA", "ROYCE", + "REBECKA", "REAGAN", "PROVIDENCIA", "PAULENE", "MISHA", "MIKI", "MARLINE", "MARICA", "LORITA", "LATOYIA", + "LASONYA", "KERSTIN", "KENDA", "KEITHA", "KATHRIN", "JAYMIE", "JACK", "GRICELDA", "GINETTE", "ERYN", + "ELINA", "ELFRIEDA", "DANYEL", "CHEREE", "CHANELLE", "BARRIE", "AVERY", "AURORE", "ANNAMARIA", "ALLEEN", + "AILENE", "AIDE", "YASMINE", "VASHTI", "VALENTINE", "TREASA", "TORY", "TIFFANEY", "SHERYLL", "SHARIE", + "SHANAE", "SAU", "RAISA", "PA", "NEDA", "MITSUKO", "MIRELLA", "MILDA", "MARYANNA", "MARAGRET", + "MABELLE", "LUETTA", "LORINA", "LETISHA", "LATARSHA", "LANELLE", "LAJUANA", "KRISSY", "KARLY", "KARENA", + "JON", "JESSIKA", "JERICA", "JEANELLE", "JANUARY", "JALISA", "JACELYN", "IZOLA", "IVEY", "GREGORY", + "EUNA", "ETHA", "DREW", "DOMITILA", "DOMINICA", "DAINA", "CREOLA", "CARLI", "CAMIE", "BUNNY", + "BRITTNY", "ASHANTI", "ANISHA", "ALEEN", "ADAH", "YASUKO", "WINTER", "VIKI", "VALRIE", "TONA", + "TINISHA", "THI", "TERISA", "TATUM", "TANEKA", "SIMONNE", "SHALANDA", "SERITA", "RESSIE", "REFUGIA", + "PAZ", "OLENE", "NA", "MERRILL", "MARGHERITA", "MANDIE", "MAN", "MAIRE", "LYNDIA", "LUCI", + "LORRIANE", "LORETA", "LEONIA", "LAVONA", "LASHAWNDA", "LAKIA", "KYOKO", "KRYSTINA", "KRYSTEN", "KENIA", + "KELSI", "JUDE", "JEANICE", "ISOBEL", "GEORGIANN", "GENNY", "FELICIDAD", "EILENE", "DEON", "DELOISE", + "DEEDEE", "DANNIE", "CONCEPTION", "CLORA", "CHERILYN", "CHANG", "CALANDRA", "BERRY", "ARMANDINA", "ANISA", + "ULA", "TIMOTHY", "TIERA", "THERESSA", "STEPHANIA", "SIMA", "SHYLA", "SHONTA", "SHERA", "SHAQUITA", + "SHALA", "SAMMY", "ROSSANA", "NOHEMI", "NERY", "MORIAH", "MELITA", "MELIDA", "MELANI", "MARYLYNN", + "MARISHA", "MARIETTE", "MALORIE", "MADELENE", "LUDIVINA", "LORIA", "LORETTE", "LORALEE", "LIANNE", "LEON", + "LAVENIA", "LAURINDA", "LASHON", "KIT", "KIMI", "KEILA", "KATELYNN", "KAI", "JONE", "JOANE", + "JI", "JAYNA", "JANELLA", "JA", "HUE", "HERTHA", "FRANCENE", "ELINORE", "DESPINA", "DELSIE", + "DEEDRA", "CLEMENCIA", "CARRY", "CAROLIN", "CARLOS", "BULAH", "BRITTANIE", "BOK", "BLONDELL", "BIBI", + "BEAULAH", "BEATA", "ANNITA", "AGRIPINA", "VIRGEN", "VALENE", "UN", "TWANDA", "TOMMYE", "TOI", + "TARRA", "TARI", "TAMMERA", "SHAKIA", "SADYE", "RUTHANNE", "ROCHEL", "RIVKA", "PURA", "NENITA", + "NATISHA", "MING", "MERRILEE", "MELODEE", "MARVIS", "LUCILLA", "LEENA", "LAVETA", "LARITA", "LANIE", + "KEREN", "ILEEN", "GEORGEANN", "GENNA", "GENESIS", "FRIDA", "EWA", "EUFEMIA", "EMELY", "ELA", + "EDYTH", "DEONNA", "DEADRA", "DARLENA", "CHANELL", "CHAN", "CATHERN", "CASSONDRA", "CASSAUNDRA", "BERNARDA", + "BERNA", "ARLINDA", "ANAMARIA", "ALBERT", "WESLEY", "VERTIE", "VALERI", "TORRI", "TATYANA", "STASIA", + "SHERISE", "SHERILL", "SEASON", "SCOTTIE", "SANDA", "RUTHE", "ROSY", "ROBERTO", "ROBBI", "RANEE", + "QUYEN", "PEARLY", "PALMIRA", "ONITA", "NISHA", "NIESHA", "NIDA", "NEVADA", "NAM", "MERLYN", + "MAYOLA", "MARYLOUISE", "MARYLAND", "MARX", "MARTH", "MARGENE", "MADELAINE", "LONDA", "LEONTINE", "LEOMA", + "LEIA", "LAWRENCE", "LAURALEE", "LANORA", "LAKITA", "KIYOKO", "KETURAH", "KATELIN", "KAREEN", "JONIE", + "JOHNETTE", "JENEE", "JEANETT", "IZETTA", "HIEDI", "HEIKE", "HASSIE", "HAROLD", "GIUSEPPINA", "GEORGANN", + "FIDELA", "FERNANDE", "ELWANDA", "ELLAMAE", "ELIZ", "DUSTI", "DOTTY", "CYNDY", "CORALIE", "CELESTA", + "ARGENTINA", "ALVERTA", "XENIA", "WAVA", "VANETTA", "TORRIE", "TASHINA", "TANDY", "TAMBRA", "TAMA", + "STEPANIE", "SHILA", "SHAUNTA", "SHARAN", "SHANIQUA", "SHAE", "SETSUKO", "SERAFINA", "SANDEE", "ROSAMARIA", + "PRISCILA", "OLINDA", "NADENE", "MUOI", "MICHELINA", "MERCEDEZ", "MARYROSE", "MARIN", "MARCENE", "MAO", + "MAGALI", "MAFALDA", "LOGAN", "LINN", "LANNIE", "KAYCE", "KAROLINE", "KAMILAH", "KAMALA", "JUSTA", + "JOLINE", "JENNINE", "JACQUETTA", "IRAIDA", "GERALD", "GEORGEANNA", "FRANCHESCA", "FAIRY", "EMELINE", "ELANE", + "EHTEL", "EARLIE", "DULCIE", "DALENE", "CRIS", "CLASSIE", "CHERE", "CHARIS", "CAROYLN", "CARMINA", + "CARITA", "BRIAN", "BETHANIE", "AYAKO", "ARICA", "AN", "ALYSA", "ALESSANDRA", "AKILAH", "ADRIEN", + "ZETTA", "YOULANDA", "YELENA", "YAHAIRA", "XUAN", "WENDOLYN", "VICTOR", "TIJUANA", "TERRELL", "TERINA", + "TERESIA", "SUZI", "SUNDAY", "SHERELL", "SHAVONDA", "SHAUNTE", "SHARDA", "SHAKITA", "SENA", "RYANN", + "RUBI", "RIVA", "REGINIA", "REA", "RACHAL", "PARTHENIA", "PAMULA", "MONNIE", "MONET", "MICHAELE", + "MELIA", "MARINE", "MALKA", "MAISHA", "LISANDRA", "LEO", "LEKISHA", "LEAN", "LAURENCE", "LAKENDRA", + "KRYSTIN", "KORTNEY", "KIZZIE", "KITTIE", "KERA", "KENDAL", "KEMBERLY", "KANISHA", "JULENE", "JULE", + "JOSHUA", "JOHANNE", "JEFFREY", "JAMEE", "HAN", "HALLEY", "GIDGET", "GALINA", "FREDRICKA", "FLETA", + "FATIMAH", "EUSEBIA", "ELZA", "ELEONORE", "DORTHEY", "DORIA", "DONELLA", "DINORAH", "DELORSE", "CLARETHA", + "CHRISTINIA", "CHARLYN", "BONG", "BELKIS", "AZZIE", "ANDERA", "AIKO", "ADENA", "YER", "YAJAIRA", + "WAN", "VANIA", "ULRIKE", "TOSHIA", "TIFANY", "STEFANY", "SHIZUE", "SHENIKA", "SHAWANNA", "SHAROLYN", + "SHARILYN", "SHAQUANA", "SHANTAY", "SEE", "ROZANNE", "ROSELEE", "RICKIE", "REMONA", "REANNA", "RAELENE", + "QUINN", "PHUNG", "PETRONILA", "NATACHA", "NANCEY", "MYRL", "MIYOKO", "MIESHA", "MERIDETH", "MARVELLA", + "MARQUITTA", "MARHTA", "MARCHELLE", "LIZETH", "LIBBIE", "LAHOMA", "LADAWN", "KINA", "KATHELEEN", "KATHARYN", + "KARISA", "KALEIGH", "JUNIE", "JULIEANN", "JOHNSIE", "JANEAN", "JAIMEE", "JACKQUELINE", "HISAKO", "HERMA", + "HELAINE", "GWYNETH", "GLENN", "GITA", "EUSTOLIA", "EMELINA", "ELIN", "EDRIS", "DONNETTE", "DONNETTA", + "DIERDRE", "DENAE", "DARCEL", "CLAUDE", "CLARISA", "CINDERELLA", "CHIA", "CHARLESETTA", "CHARITA", "CELSA", + "CASSY", "CASSI", "CARLEE", "BRUNA", "BRITTANEY", "BRANDE", "BILLI", "BAO", "ANTONETTA", "ANGLA", + "ANGELYN", "ANALISA", "ALANE", "WENONA", "WENDIE", "VERONIQUE", "VANNESA", "TOBIE", "TEMPIE", "SUMIKO", + "SULEMA", "SPARKLE", "SOMER", "SHEBA", "SHAYNE", "SHARICE", "SHANEL", "SHALON", "SAGE", "ROY", + "ROSIO", "ROSELIA", "RENAY", "REMA", "REENA", "PORSCHE", "PING", "PEG", "OZIE", "ORETHA", + "ORALEE", "ODA", "NU", "NGAN", "NAKESHA", "MILLY", "MARYBELLE", "MARLIN", "MARIS", "MARGRETT", + "MARAGARET", "MANIE", "LURLENE", "LILLIA", "LIESELOTTE", "LAVELLE", "LASHAUNDA", "LAKEESHA", "KEITH", "KAYCEE", + "KALYN", "JOYA", "JOETTE", "JENAE", "JANIECE", "ILLA", "GRISEL", "GLAYDS", "GENEVIE", "GALA", + "FREDDA", "FRED", "ELMER", "ELEONOR", "DEBERA", "DEANDREA", "DAN", "CORRINNE", "CORDIA", "CONTESSA", + "COLENE", "CLEOTILDE", "CHARLOTT", "CHANTAY", "CECILLE", "BEATRIS", "AZALEE", "ARLEAN", "ARDATH", "ANJELICA", + "ANJA", "ALFREDIA", "ALEISHA", "ADAM", "ZADA", "YUONNE", "XIAO", "WILLODEAN", "WHITLEY", "VENNIE", + "VANNA", "TYISHA", "TOVA", "TORIE", "TONISHA", "TILDA", "TIEN", "TEMPLE", "SIRENA", "SHERRIL", + "SHANTI", "SHAN", "SENAIDA", "SAMELLA", "ROBBYN", "RENDA", "REITA", "PHEBE", "PAULITA", "NOBUKO", + "NGUYET", "NEOMI", "MOON", "MIKAELA", "MELANIA", "MAXIMINA", "MARG", "MAISIE", "LYNNA", "LILLI", + "LAYNE", "LASHAUN", "LAKENYA", "LAEL", "KIRSTIE", "KATHLINE", "KASHA", "KARLYN", "KARIMA", "JOVAN", + "JOSEFINE", "JENNELL", "JACQUI", "JACKELYN", "HYO", "HIEN", "GRAZYNA", "FLORRIE", "FLORIA", "ELEONORA", + "DWANA", "DORLA", "DONG", "DELMY", "DEJA", "DEDE", "DANN", "CRYSTA", "CLELIA", "CLARIS", + "CLARENCE", "CHIEKO", "CHERLYN", "CHERELLE", "CHARMAIN", "CHARA", "CAMMY", "BEE", "ARNETTE", "ARDELLE", + "ANNIKA", "AMIEE", "AMEE", "ALLENA", "YVONE", "YUKI", "YOSHIE", "YEVETTE", "YAEL", "WILLETTA", + "VONCILE", "VENETTA", "TULA", "TONETTE", "TIMIKA", "TEMIKA", "TELMA", "TEISHA", "TAREN", "TA", + "STACEE", "SHIN", "SHAWNTA", "SATURNINA", "RICARDA", "POK", "PASTY", "ONIE", "NUBIA", "MORA", + "MIKE", "MARIELLE", "MARIELLA", "MARIANELA", "MARDELL", "MANY", "LUANNA", "LOISE", "LISABETH", "LINDSY", + "LILLIANA", "LILLIAM", "LELAH", "LEIGHA", "LEANORA", "LANG", "KRISTEEN", "KHALILAH", "KEELEY", "KANDRA", + "JUNKO", "JOAQUINA", "JERLENE", "JANI", "JAMIKA", "JAME", "HSIU", "HERMILA", "GOLDEN", "GENEVIVE", + "EVIA", "EUGENA", "EMMALINE", "ELFREDA", "ELENE", "DONETTE", "DELCIE", "DEEANNA", "DARCEY", "CUC", + "CLARINDA", "CIRA", "CHAE", "CELINDA", "CATHERYN", "CATHERIN", "CASIMIRA", "CARMELIA", "CAMELLIA", "BREANA", + "BOBETTE", "BERNARDINA", "BEBE", "BASILIA", "ARLYNE", "AMAL", "ALAYNA", "ZONIA", "ZENIA", "YURIKO", + "YAEKO", "WYNELL", "WILLOW", "WILLENA", "VERNIA", "TU", "TRAVIS", "TORA", "TERRILYN", "TERICA", + "TENESHA", "TAWNA", "TAJUANA", "TAINA", "STEPHNIE", "SONA", "SOL", "SINA", "SHONDRA", "SHIZUKO", + "SHERLENE", "SHERICE", "SHARIKA", "ROSSIE", "ROSENA", "RORY", "RIMA", "RIA", "RHEBA", "RENNA", + "PETER", "NATALYA", "NANCEE", "MELODI", "MEDA", "MAXIMA", "MATHA", "MARKETTA", "MARICRUZ", "MARCELENE", + "MALVINA", "LUBA", "LOUETTA", "LEIDA", "LECIA", "LAURAN", "LASHAWNA", "LAINE", "KHADIJAH", "KATERINE", + "KASI", "KALLIE", "JULIETTA", "JESUSITA", "JESTINE", "JESSIA", "JEREMY", "JEFFIE", "JANYCE", "ISADORA", + "GEORGIANNE", "FIDELIA", "EVITA", "EURA", "EULAH", "ESTEFANA", "ELSY", "ELIZABET", "ELADIA", "DODIE", + "DION", "DIA", "DENISSE", "DELORAS", "DELILA", "DAYSI", "DAKOTA", "CURTIS", "CRYSTLE", "CONCHA", + "COLBY", "CLARETTA", "CHU", "CHRISTIA", "CHARLSIE", "CHARLENA", "CARYLON", "BETTYANN", "ASLEY", "ASHLEA", + "AMIRA", "AI", "AGUEDA", "AGNUS", "YUETTE", "VINITA", "VICTORINA", "TYNISHA", "TREENA", "TOCCARA", + "TISH", "THOMASENA", "TEGAN", "SOILA", "SHILOH", "SHENNA", "SHARMAINE", "SHANTAE", "SHANDI", "SEPTEMBER", + "SARAN", "SARAI", "SANA", "SAMUEL", "SALLEY", "ROSETTE", "ROLANDE", "REGINE", "OTELIA", "OSCAR", + "OLEVIA", "NICHOLLE", "NECOLE", "NAIDA", "MYRTA", "MYESHA", "MITSUE", "MINTA", "MERTIE", "MARGY", + "MAHALIA", "MADALENE", "LOVE", "LOURA", "LOREAN", "LEWIS", "LESHA", "LEONIDA", "LENITA", "LAVONE", + "LASHELL", "LASHANDRA", "LAMONICA", "KIMBRA", "KATHERINA", "KARRY", "KANESHA", "JULIO", "JONG", "JENEVA", + "JAQUELYN", "HWA", "GILMA", "GHISLAINE", "GERTRUDIS", "FRANSISCA", "FERMINA", "ETTIE", "ETSUKO", "ELLIS", + "ELLAN", "ELIDIA", "EDRA", "DORETHEA", "DOREATHA", "DENYSE", "DENNY", "DEETTA", "DAINE", "CYRSTAL", + "CORRIN", "CAYLA", "CARLITA", "CAMILA", "BURMA", "BULA", "BUENA", "BLAKE", "BARABARA", "AVRIL", + "AUSTIN", "ALAINE", "ZANA", "WILHEMINA", "WANETTA", "VIRGIL", "VI", "VERONIKA", "VERNON", "VERLINE", + "VASILIKI", "TONITA", "TISA", "TEOFILA", "TAYNA", "TAUNYA", "TANDRA", "TAKAKO", "SUNNI", "SUANNE", + "SIXTA", "SHARELL", "SEEMA", "RUSSELL", "ROSENDA", "ROBENA", "RAYMONDE", "PEI", "PAMILA", "OZELL", + "NEIDA", "NEELY", "MISTIE", "MICHA", "MERISSA", "MAURITA", "MARYLN", "MARYETTA", "MARSHALL", "MARCELL", + "MALENA", "MAKEDA", "MADDIE", "LOVETTA", "LOURIE", "LORRINE", "LORILEE", "LESTER", "LAURENA", "LASHAY", + "LARRAINE", "LAREE", "LACRESHA", "KRISTLE", "KRISHNA", "KEVA", "KEIRA", "KAROLE", "JOIE", "JINNY", + "JEANNETTA", "JAMA", "HEIDY", "GILBERTE", "GEMA", "FAVIOLA", "EVELYNN", "ENDA", "ELLI", "ELLENA", + "DIVINA", "DAGNY", "COLLENE", "CODI", "CINDIE", "CHASSIDY", "CHASIDY", "CATRICE", "CATHERINA", "CASSEY", + "CAROLL", "CARLENA", "CANDRA", "CALISTA", "BRYANNA", "BRITTENY", "BEULA", "BARI", "AUDRIE", "AUDRIA", + "ARDELIA", "ANNELLE", "ANGILA", "ALONA", "ALLYN", "DOUGLAS", "ROGER", "JONATHAN", "RALPH", "NICHOLAS", + "BENJAMIN", "BRUCE", "HARRY", "WAYNE", "STEVE", "HOWARD", "ERNEST", "PHILLIP", "TODD", "CRAIG", + "ALAN", "PHILIP", "EARL", "DANNY", "BRYAN", "STANLEY", "LEONARD", "NATHAN", "MANUEL", "RODNEY", + "MARVIN", "VINCENT", "JEFFERY", "JEFF", "CHAD", "JACOB", "ALFRED", "BRADLEY", "HERBERT", "FREDERICK", + "EDWIN", "DON", "RICKY", "RANDALL", "BARRY", "BERNARD", "LEROY", "MARCUS", "THEODORE", "CLIFFORD", + "MIGUEL", "JIM", "TOM", "CALVIN", "BILL", "LLOYD", "DEREK", "WARREN", "DARRELL", "JEROME", + "FLOYD", "ALVIN", "TIM", "GORDON", "GREG", "JORGE", "DUSTIN", "PEDRO", "DERRICK", "ZACHARY", + "HERMAN", "GLEN", "HECTOR", "RICARDO", "RICK", "BRENT", "RAMON", "GILBERT", "MARC", "REGINALD", + "RUBEN", "NATHANIEL", "RAFAEL", "EDGAR", "MILTON", "RAUL", "BEN", "CHESTER", "DUANE", "FRANKLIN", + "BRAD", "RON", "ROLAND", "ARNOLD", "HARVEY", "JARED", "ERIK", "DARRYL", "NEIL", "JAVIER", + "FERNANDO", "CLINTON", "TED", "MATHEW", "TYRONE", "DARREN", "LANCE", "KURT", "ALLAN", "NELSON", + "GUY", "CLAYTON", "HUGH", "MAX", "DWAYNE", "DWIGHT", "ARMANDO", "FELIX", "EVERETT", "IAN", + "WALLACE", "KEN", "BOB", "ALFREDO", "ALBERTO", "DAVE", "IVAN", "BYRON", "ISAAC", "MORRIS", + "CLIFTON", "WILLARD", "ROSS", "ANDY", "SALVADOR", "KIRK", "SERGIO", "SETH", "KENT", "TERRANCE", + "EDUARDO", "TERRENCE", "ENRIQUE", "WADE", "STUART", "FREDRICK", "ARTURO", "ALEJANDRO", "NICK", "LUTHER", + "WENDELL", "JEREMIAH", "JULIUS", "OTIS", "TREVOR", "OLIVER", "LUKE", "HOMER", "GERARD", "DOUG", + "KENNY", "HUBERT", "LYLE", "MATT", "ALFONSO", "ORLANDO", "REX", "CARLTON", "ERNESTO", "NEAL", + "PABLO", "LORENZO", "OMAR", "WILBUR", "GRANT", "HORACE", "RODERICK", "ABRAHAM", "WILLIS", "RICKEY", + "ANDRES", "CESAR", "JOHNATHAN", "MALCOLM", "RUDOLPH", "DAMON", "KELVIN", "PRESTON", "ALTON", "ARCHIE", + "MARCO", "WM", "PETE", "RANDOLPH", "GARRY", "GEOFFREY", "JONATHON", "FELIPE", "GERARDO", "ED", + "DOMINIC", "DELBERT", "COLIN", "GUILLERMO", "EARNEST", "LUCAS", "BENNY", "SPENCER", "RODOLFO", "MYRON", + "EDMUND", "GARRETT", "SALVATORE", "CEDRIC", "LOWELL", "GREGG", "SHERMAN", "WILSON", "SYLVESTER", "ROOSEVELT", + "ISRAEL", "JERMAINE", "FORREST", "WILBERT", "LELAND", "SIMON", "CLARK", "IRVING", "BRYANT", "OWEN", + "RUFUS", "WOODROW", "KRISTOPHER", "MACK", "LEVI", "MARCOS", "GUSTAVO", "JAKE", "LIONEL", "GILBERTO", + "CLINT", "NICOLAS", "ISMAEL", "ORVILLE", "ERVIN", "DEWEY", "AL", "WILFRED", "JOSH", "HUGO", + "IGNACIO", "CALEB", "TOMAS", "SHELDON", "ERICK", "STEWART", "DOYLE", "DARREL", "ROGELIO", "TERENCE", + "SANTIAGO", "ALONZO", "ELIAS", "BERT", "ELBERT", "RAMIRO", "CONRAD", "NOAH", "GRADY", "PHIL", + "CORNELIUS", "LAMAR", "ROLANDO", "CLAY", "PERCY", "DEXTER", "BRADFORD", "DARIN", "AMOS", "MOSES", + "IRVIN", "SAUL", "ROMAN", "RANDAL", "TIMMY", "DARRIN", "WINSTON", "BRENDAN", "ABEL", "DOMINICK", + "BOYD", "EMILIO", "ELIJAH", "DOMINGO", "EMMETT", "MARLON", "EMANUEL", "JERALD", "EDMOND", "EMIL", + "DEWAYNE", "WILL", "OTTO", "TEDDY", "REYNALDO", "BRET", "JESS", "TRENT", "HUMBERTO", "EMMANUEL", + "STEPHAN", "VICENTE", "LAMONT", "GARLAND", "MILES", "EFRAIN", "HEATH", "RODGER", "HARLEY", "ETHAN", + "ELDON", "ROCKY", "PIERRE", "JUNIOR", "FREDDY", "ELI", "BRYCE", "ANTOINE", "STERLING", "CHASE", + "GROVER", "ELTON", "CLEVELAND", "DYLAN", "CHUCK", "DAMIAN", "REUBEN", "STAN", "AUGUST", "LEONARDO", + "JASPER", "RUSSEL", "ERWIN", "BENITO", "HANS", "MONTE", "BLAINE", "ERNIE", "CURT", "QUENTIN", + "AGUSTIN", "MURRAY", "JAMAL", "ADOLFO", "HARRISON", "TYSON", "BURTON", "BRADY", "ELLIOTT", "WILFREDO", + "BART", "JARROD", "VANCE", "DENIS", "DAMIEN", "JOAQUIN", "HARLAN", "DESMOND", "ELLIOT", "DARWIN", + "GREGORIO", "BUDDY", "XAVIER", "KERMIT", "ROSCOE", "ESTEBAN", "ANTON", "SOLOMON", "SCOTTY", "NORBERT", + "ELVIN", "WILLIAMS", "NOLAN", "ROD", "QUINTON", "HAL", "BRAIN", "ROB", "ELWOOD", "KENDRICK", + "DARIUS", "MOISES", "FIDEL", "THADDEUS", "CLIFF", "MARCEL", "JACKSON", "RAPHAEL", "BRYON", "ARMAND", + "ALVARO", "JEFFRY", "DANE", "JOESPH", "THURMAN", "NED", "RUSTY", "MONTY", "FABIAN", "REGGIE", + "MASON", "GRAHAM", "ISAIAH", "VAUGHN", "GUS", "LOYD", "DIEGO", "ADOLPH", "NORRIS", "MILLARD", + "ROCCO", "GONZALO", "DERICK", "RODRIGO", "WILEY", "RIGOBERTO", "ALPHONSO", "TY", "NOE", "VERN", + "REED", "JEFFERSON", "ELVIS", "BERNARDO", "MAURICIO", "HIRAM", "DONOVAN", "BASIL", "RILEY", "NICKOLAS", + "MAYNARD", "SCOT", "VINCE", "QUINCY", "EDDY", "SEBASTIAN", "FEDERICO", "ULYSSES", "HERIBERTO", "DONNELL", + "COLE", "DAVIS", "GAVIN", "EMERY", "WARD", "ROMEO", "JAYSON", "DANTE", "CLEMENT", "COY", + "MAXWELL", "JARVIS", "BRUNO", "ISSAC", "DUDLEY", "BROCK", "SANFORD", "CARMELO", "BARNEY", "NESTOR", + "STEFAN", "DONNY", "ART", "LINWOOD", "BEAU", "WELDON", "GALEN", "ISIDRO", "TRUMAN", "DELMAR", + "JOHNATHON", "SILAS", "FREDERIC", "DICK", "IRWIN", "MERLIN", "CHARLEY", "MARCELINO", "HARRIS", "CARLO", + "TRENTON", "KURTIS", "HUNTER", "AURELIO", "WINFRED", "VITO", "COLLIN", "DENVER", "CARTER", "LEONEL", + "EMORY", "PASQUALE", "MOHAMMAD", "MARIANO", "DANIAL", "LANDON", "DIRK", "BRANDEN", "ADAN", "BUFORD", + "GERMAN", "WILMER", "EMERSON", "ZACHERY", "FLETCHER", "JACQUES", "ERROL", "DALTON", "MONROE", "JOSUE", + "EDWARDO", "BOOKER", "WILFORD", "SONNY", "SHELTON", "CARSON", "THERON", "RAYMUNDO", "DAREN", "HOUSTON", + "ROBBY", "LINCOLN", "GENARO", "BENNETT", "OCTAVIO", "CORNELL", "HUNG", "ARRON", "ANTONY", "HERSCHEL", + "GIOVANNI", "GARTH", "CYRUS", "CYRIL", "RONNY", "LON", "FREEMAN", "DUNCAN", "KENNITH", "CARMINE", + "ERICH", "CHADWICK", "WILBURN", "RUSS", "REID", "MYLES", "ANDERSON", "MORTON", "JONAS", "FOREST", + "MITCHEL", "MERVIN", "ZANE", "RICH", "JAMEL", "LAZARO", "ALPHONSE", "RANDELL", "MAJOR", "JARRETT", + "BROOKS", "ABDUL", "LUCIANO", "SEYMOUR", "EUGENIO", "MOHAMMED", "VALENTIN", "CHANCE", "ARNULFO", "LUCIEN", + "FERDINAND", "THAD", "EZRA", "ALDO", "RUBIN", "ROYAL", "MITCH", "EARLE", "ABE", "WYATT", + "MARQUIS", "LANNY", "KAREEM", "JAMAR", "BORIS", "ISIAH", "EMILE", "ELMO", "ARON", "LEOPOLDO", + "EVERETTE", "JOSEF", "ELOY", "RODRICK", "REINALDO", "LUCIO", "JERROD", "WESTON", "HERSHEL", "BARTON", + "PARKER", "LEMUEL", "BURT", "JULES", "GIL", "ELISEO", "AHMAD", "NIGEL", "EFREN", "ANTWAN", + "ALDEN", "MARGARITO", "COLEMAN", "DINO", "OSVALDO", "LES", "DEANDRE", "NORMAND", "KIETH", "TREY", + "NORBERTO", "NAPOLEON", "JEROLD", "FRITZ", "ROSENDO", "MILFORD", "CHRISTOPER", "ALFONZO", "LYMAN", "JOSIAH", + "BRANT", "WILTON", "RICO", "JAMAAL", "DEWITT", "BRENTON", "OLIN", "FOSTER", "FAUSTINO", "CLAUDIO", + "JUDSON", "GINO", "EDGARDO", "ALEC", "TANNER", "JARRED", "DONN", "TAD", "PRINCE", "PORFIRIO", + "ODIS", "LENARD", "CHAUNCEY", "TOD", "MEL", "MARCELO", "KORY", "AUGUSTUS", "KEVEN", "HILARIO", + "BUD", "SAL", "ORVAL", "MAURO", "ZACHARIAH", "OLEN", "ANIBAL", "MILO", "JED", "DILLON", + "AMADO", "NEWTON", "LENNY", "RICHIE", "HORACIO", "BRICE", "MOHAMED", "DELMER", "DARIO", "REYES", + "MAC", "JONAH", "JERROLD", "ROBT", "HANK", "RUPERT", "ROLLAND", "KENTON", "DAMION", "ANTONE", + "WALDO", "FREDRIC", "BRADLY", "KIP", "BURL", "WALKER", "TYREE", "JEFFEREY", "AHMED", "WILLY", + "STANFORD", "OREN", "NOBLE", "MOSHE", "MIKEL", "ENOCH", "BRENDON", "QUINTIN", "JAMISON", "FLORENCIO", + "DARRICK", "TOBIAS", "HASSAN", "GIUSEPPE", "DEMARCUS", "CLETUS", "TYRELL", "LYNDON", "KEENAN", "WERNER", + "GERALDO", "COLUMBUS", "CHET", "BERTRAM", "MARKUS", "HUEY", "HILTON", "DWAIN", "DONTE", "TYRON", + "OMER", "ISAIAS", "HIPOLITO", "FERMIN", "ADALBERTO", "BO", "BARRETT", "TEODORO", "MCKINLEY", "MAXIMO", + "GARFIELD", "RALEIGH", "LAWERENCE", "ABRAM", "RASHAD", "KING", "EMMITT", "DARON", "SAMUAL", "MIQUEL", + "EUSEBIO", "DOMENIC", "DARRON", "BUSTER", "WILBER", "RENATO", "JC", "HOYT", "HAYWOOD", "EZEKIEL", + "CHAS", "FLORENTINO", "ELROY", "CLEMENTE", "ARDEN", "NEVILLE", "EDISON", "DESHAWN", "NATHANIAL", "JORDON", + "DANILO", "CLAUD", "SHERWOOD", "RAYMON", "RAYFORD", "CRISTOBAL", "AMBROSE", "TITUS", "HYMAN", "FELTON", + "EZEQUIEL", "ERASMO", "STANTON", "LONNY", "LEN", "IKE", "MILAN", "LINO", "JAROD", "HERB", + "ANDREAS", "WALTON", "RHETT", "PALMER", "DOUGLASS", "CORDELL", "OSWALDO", "ELLSWORTH", "VIRGILIO", "TONEY", + "NATHANAEL", "DEL", "BENEDICT", "MOSE", "JOHNSON", "ISREAL", "GARRET", "FAUSTO", "ASA", "ARLEN", + "ZACK", "WARNER", "MODESTO", "FRANCESCO", "MANUAL", "GAYLORD", "GASTON", "FILIBERTO", "DEANGELO", "MICHALE", + "GRANVILLE", "WES", "MALIK", "ZACKARY", "TUAN", "ELDRIDGE", "CRISTOPHER", "CORTEZ", "ANTIONE", "MALCOM", + "LONG", "KOREY", "JOSPEH", "COLTON", "WAYLON", "VON", "HOSEA", "SHAD", "SANTO", "RUDOLF", + "ROLF", "REY", "RENALDO", "MARCELLUS", "LUCIUS", "KRISTOFER", "BOYCE", "BENTON", "HAYDEN", "HARLAND", + "ARNOLDO", "RUEBEN", "LEANDRO", "KRAIG", "JERRELL", "JEROMY", "HOBERT", "CEDRICK", "ARLIE", "WINFORD", + "WALLY", "LUIGI", "KENETH", "JACINTO", "GRAIG", "FRANKLYN", "EDMUNDO", "SID", "PORTER", "LEIF", + "JERAMY", "BUCK", "WILLIAN", "VINCENZO", "SHON", "LYNWOOD", "JERE", "HAI", "ELDEN", "DORSEY", + "DARELL", "BRODERICK", "ALONSO" + ] + total_sum = 0 + temp_sum = 0 + name.sort() + for i in range(len(name)): + for j in name[i]: + temp_sum += ord(j) - ord('A') + 1 + total_sum += (i + 1) * temp_sum + temp_sum = 0 + print(total_sum) + + +if __name__ == '__main__': + main() diff --git a/project_euler/Problem 24/sol1.py b/project_euler/Problem 24/sol1.py new file mode 100644 index 000000000..b20493cb0 --- /dev/null +++ b/project_euler/Problem 24/sol1.py @@ -0,0 +1,7 @@ +from itertools import permutations +def main(): + result=list(map("".join, permutations('0123456789'))) + print(result[999999]) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/project_euler/Problem 25/sol1.py b/project_euler/Problem 25/sol1.py new file mode 100644 index 000000000..f8cea3093 --- /dev/null +++ b/project_euler/Problem 25/sol1.py @@ -0,0 +1,31 @@ +from __future__ import print_function + +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +def fibonacci(n): + if n == 1 or type(n) is not int: + return 0 + elif n == 2: + return 1 + else: + sequence = [0, 1] + for i in xrange(2, n+1): + sequence.append(sequence[i-1] + sequence[i-2]) + + return sequence[n] + +def fibonacci_digits_index(n): + digits = 0 + index = 2 + + while digits < n: + index += 1 + digits = len(str(fibonacci(index))) + + return index + +if __name__ == '__main__': + print(fibonacci_digits_index(1000)) \ No newline at end of file diff --git a/project_euler/Problem 28/sol1.py b/project_euler/Problem 28/sol1.py new file mode 100644 index 000000000..4942115ce --- /dev/null +++ b/project_euler/Problem 28/sol1.py @@ -0,0 +1,29 @@ +from __future__ import print_function +from math import ceil + +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +def diagonal_sum(n): + total = 1 + + for i in xrange(1, int(ceil(n/2.0))): + odd = 2*i+1 + even = 2*i + total = total + 4*odd**2 - 6*even + + return total + +if __name__ == '__main__': + import sys + + if len(sys.argv) == 1: + print(diagonal_sum(1001)) + else: + try: + n = int(sys.argv[1]) + diagonal_sum(n) + except ValueError: + print('Invalid entry - please enter a number') \ No newline at end of file diff --git a/project_euler/Problem 29/solution.py b/project_euler/Problem 29/solution.py new file mode 100644 index 000000000..64d35c84d --- /dev/null +++ b/project_euler/Problem 29/solution.py @@ -0,0 +1,33 @@ +def main(): + """ + Consider all integer combinations of ab for 2 <= a <= 5 and 2 <= b <= 5: + + 22=4, 23=8, 24=16, 25=32 + 32=9, 33=27, 34=81, 35=243 + 42=16, 43=64, 44=256, 45=1024 + 52=25, 53=125, 54=625, 55=3125 + If they are then placed in numerical order, with any repeats removed, + we get the following sequence of 15 distinct terms: + + 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125 + + How many distinct terms are in the sequence generated by ab + for 2 <= a <= 100 and 2 <= b <= 100? + """ + + collectPowers = set() + + currentPow = 0 + + N = 101 # maximum limit + + for a in range(2, N): + for b in range(2, N): + currentPow = a**b # calculates the current power + collectPowers.add(currentPow) # adds the result to the set + + print("Number of terms ", len(collectPowers)) + + +if __name__ == '__main__': + main() diff --git a/project_euler/Problem 36/sol1.py b/project_euler/Problem 36/sol1.py new file mode 100644 index 000000000..d78e7e59f --- /dev/null +++ b/project_euler/Problem 36/sol1.py @@ -0,0 +1,30 @@ +from __future__ import print_function +''' +Double-base palindromes +Problem 36 +The decimal number, 585 = 10010010012 (binary), is palindromic in both bases. + +Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2. + +(Please note that the palindromic number, in either base, may not include leading zeros.) +''' +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +def is_palindrome(n): + n = str(n) + + if n == n[::-1]: + return True + else: + return False + +total = 0 + +for i in xrange(1, 1000000): + if is_palindrome(i) and is_palindrome(bin(i).split('b')[1]): + total += i + +print(total) \ No newline at end of file diff --git a/project_euler/Problem 40/sol1.py b/project_euler/Problem 40/sol1.py new file mode 100644 index 000000000..ab4017512 --- /dev/null +++ b/project_euler/Problem 40/sol1.py @@ -0,0 +1,26 @@ +#-.- coding: latin-1 -.- +from __future__ import print_function +''' +Champernowne's constant +Problem 40 +An irrational decimal fraction is created by concatenating the positive integers: + +0.123456789101112131415161718192021... + +It can be seen that the 12th digit of the fractional part is 1. + +If dn represents the nth digit of the fractional part, find the value of the following expression. + +d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000 +''' + +constant = [] +i = 1 + +while len(constant) < 1e6: + constant.append(str(i)) + i += 1 + +constant = ''.join(constant) + +print(int(constant[0])*int(constant[9])*int(constant[99])*int(constant[999])*int(constant[9999])*int(constant[99999])*int(constant[999999])) \ No newline at end of file diff --git a/project_euler/Problem 48/sol1.py b/project_euler/Problem 48/sol1.py new file mode 100644 index 000000000..5c4bdb0f6 --- /dev/null +++ b/project_euler/Problem 48/sol1.py @@ -0,0 +1,21 @@ +from __future__ import print_function +''' +Self Powers +Problem 48 + +The series, 11 + 22 + 33 + ... + 1010 = 10405071317. + +Find the last ten digits of the series, 11 + 22 + 33 + ... + 10001000. +''' + +try: + xrange +except NameError: + xrange = range + +total = 0 +for i in xrange(1, 1001): + total += i**i + + +print(str(total)[-10:]) \ No newline at end of file diff --git a/project_euler/Problem 52/sol1.py b/project_euler/Problem 52/sol1.py new file mode 100644 index 000000000..376b4cfa1 --- /dev/null +++ b/project_euler/Problem 52/sol1.py @@ -0,0 +1,23 @@ +from __future__ import print_function +''' +Permuted multiples +Problem 52 + +It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order. + +Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits. +''' +i = 1 + +while True: + if sorted(list(str(i))) == \ + sorted(list(str(2*i))) == \ + sorted(list(str(3*i))) == \ + sorted(list(str(4*i))) == \ + sorted(list(str(5*i))) == \ + sorted(list(str(6*i))): + break + + i += 1 + +print(i) \ No newline at end of file diff --git a/project_euler/Problem 53/sol1.py b/project_euler/Problem 53/sol1.py new file mode 100644 index 000000000..ed6d5329e --- /dev/null +++ b/project_euler/Problem 53/sol1.py @@ -0,0 +1,36 @@ +#-.- coding: latin-1 -.- +from __future__ import print_function +from math import factorial +''' +Combinatoric selections +Problem 53 + +There are exactly ten ways of selecting three from five, 12345: + +123, 124, 125, 134, 135, 145, 234, 235, 245, and 345 + +In combinatorics, we use the notation, 5C3 = 10. + +In general, + +nCr = n!/(r!(n−r)!),where r ≤ n, n! = n×(n−1)×...×3×2×1, and 0! = 1. +It is not until n = 23, that a value exceeds one-million: 23C10 = 1144066. + +How many, not necessarily distinct, values of nCr, for 1 ≤ n ≤ 100, are greater than one-million? +''' +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +def combinations(n, r): + return factorial(n)/(factorial(r)*factorial(n-r)) + +total = 0 + +for i in xrange(1, 101): + for j in xrange(1, i+1): + if combinations(i, j) > 1e6: + total += 1 + +print(total) \ No newline at end of file diff --git a/project_euler/Problem 76/sol1.py b/project_euler/Problem 76/sol1.py new file mode 100644 index 000000000..2832f6d7a --- /dev/null +++ b/project_euler/Problem 76/sol1.py @@ -0,0 +1,35 @@ +from __future__ import print_function +''' +Counting Summations +Problem 76 + +It is possible to write five as a sum in exactly six different ways: + +4 + 1 +3 + 2 +3 + 1 + 1 +2 + 2 + 1 +2 + 1 + 1 + 1 +1 + 1 + 1 + 1 + 1 + +How many different ways can one hundred be written as a sum of at least two positive integers? +''' +try: + xrange #Python 2 +except NameError: + xrange = range #Python 3 + +def partition(m): + memo = [[0 for _ in xrange(m)] for _ in xrange(m+1)] + for i in xrange(m+1): + memo[i][0] = 1 + + for n in xrange(m+1): + for k in xrange(1, m): + memo[n][k] += memo[n][k-1] + if n > k: + memo[n][k] += memo[n-k-1][k] + + return (memo[m][m-1] - 1) + +print(partition(100)) \ No newline at end of file diff --git a/project_euler/README.md b/project_euler/README.md new file mode 100644 index 000000000..9f77f719f --- /dev/null +++ b/project_euler/README.md @@ -0,0 +1,58 @@ +# ProjectEuler + +Problems are taken from https://projecteuler.net/. + +Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical +insights to solve. Project Euler is ideal for mathematicians who are learning to code. + +Here the efficiency of your code is also checked. +I've tried to provide all the best possible solutions. + +PROBLEMS: + +1. If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3,5,6 and 9. The sum of these multiples is 23. + Find the sum of all the multiples of 3 or 5 below N. + +2. Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, + the first 10 terms will be: + 1,2,3,5,8,13,21,34,55,89,.. + By considering the terms in the Fibonacci sequence whose values do not exceed n, find the sum of the even-valued terms. + e.g. for n=10, we have {2,8}, sum is 10. + +3. The prime factors of 13195 are 5,7,13 and 29. What is the largest prime factor of a given number N? + e.g. for 10, largest prime factor = 5. For 17, largest prime factor = 17. + +4. A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. + Find the largest palindrome made from the product of two 3-digit numbers which is less than N. + +5. 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. + What is the smallest positive number that is evenly divisible(divisible with no remainder) by all of the numbers from 1 to N? + +6. The sum of the squares of the first ten natural numbers is, + 1^2 + 2^2 + ... + 10^2 = 385 + The square of the sum of the first ten natural numbers is, + (1 + 2 + ... + 10)^2 = 552 = 3025 + Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 − 385 = 2640. + Find the difference between the sum of the squares of the first N natural numbers and the square of the sum. + +7. By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. + What is the Nth prime number? + +9. A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, + a^2 + b^2 = c^2 + There exists exactly one Pythagorean triplet for which a + b + c = 1000. + Find the product abc. + +14. The following iterative sequence is defined for the set of positive integers: + n → n/2 (n is even) + n → 3n + 1 (n is odd) + Using the rule above and starting with 13, we generate the following sequence: + 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 + Which starting number, under one million, produces the longest chain? + +16. 2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26. + What is the sum of the digits of the number 2^1000? +20. n! means n × (n − 1) × ... × 3 × 2 × 1 + For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, + and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27. + Find the sum of the digits in the number 100! diff --git a/simple_client_server/README.md b/simple_client_server/README.md new file mode 100644 index 000000000..f51947f21 --- /dev/null +++ b/simple_client_server/README.md @@ -0,0 +1,6 @@ +# simple client server + +#### Note: +- Run **`server.py`** first. +- Now, run **`client.py`**. +- verify the output. diff --git a/simple_client_server/client.py b/simple_client_server/client.py new file mode 100644 index 000000000..c91e6233a --- /dev/null +++ b/simple_client_server/client.py @@ -0,0 +1,14 @@ +# client.py + +import socket + +HOST, PORT = '127.0.0.1', 1400 + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect((HOST, PORT)) + +s.send(b'Hello World') +data = s.recv(1024) + +s.close() +print(repr(data.decode('ascii'))) diff --git a/simple_client_server/server.py b/simple_client_server/server.py new file mode 100644 index 000000000..c6b661d99 --- /dev/null +++ b/simple_client_server/server.py @@ -0,0 +1,21 @@ +# server.py + +import socket + +HOST, PORT = '127.0.0.1', 1400 + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.bind((HOST, PORT)) +s.listen(1) + +conn, addr = s.accept() + +print('connected to:', addr) + +while 1: + data = conn.recv(1024) + if not data: + break + conn.send(data + b' [ addition by server ]') + +conn.close() diff --git a/tags b/tags new file mode 100644 index 000000000..46f6330e8 --- /dev/null +++ b/tags @@ -0,0 +1,1373 @@ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ +!_TAG_PROGRAM_AUTHOR Universal Ctags Team // +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ +!_TAG_PROGRAM_URL https://ctags.io/ /official site/ +!_TAG_PROGRAM_VERSION 0.0.0 /619a6fac/ +- returns a random matrix WxH with integer components between 'a' and 'b' linear_algebra_python/README.md /^ - returns a random matrix WxH with integer components between 'a' and 'b' $/;" s +A data_structures/binary tree/LazySegmentTree.py /^ A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8]$/;" v +A data_structures/binary tree/SegmentTree.py /^ A = [1,2,-4,7,3,-5,6,11,-20,9,14,15,5,2,-8]$/;" v +AVL data_structures/avl.py /^class AVL:$/;" c +AdjacencyList data_structures/graph/graph.py /^class AdjacencyList(object):$/;" c +All algorithms implemented in Python (for education) README.md /^### All algorithms implemented in Python (for education)$/;" S +Array Elements sorts/normal_distribution_QuickSort_README.md /^## Array Elements$/;" s +BFS data_structures/graph/breadth_first_search.py /^ def BFS(self, startVertex):$/;" m class:Graph +BFS networking_flow/Ford_Fulkerson.py /^def BFS(graph, s, t, parent):$/;" f +BFS networking_flow/Minimum_cut.py /^def BFS(graph, s, t, parent):$/;" f +BLOCK_FILENAME_FORMAT sorts/external-sort.py /^ BLOCK_FILENAME_FORMAT = 'block_{0}.dat'$/;" v class:FileSplitter +BPNN neural_network/bpnn.py /^class BPNN():$/;" c +BYTE_SIZE ciphers/rsa_cipher.py /^BYTE_SIZE = 256$/;" v +BellmanFord data_structures/graph/bellman_ford.py /^def BellmanFord(graph, V, E, src):$/;" f +Binary README.md /^### Binary$/;" S +BinarySearchTree data_structures/binary tree/binary_search_tree.py /^class BinarySearchTree:$/;" c +Bubble README.md /^### Bubble$/;" S +Bucket README.md /^### Bucket$/;" S +CNN neural_network/convolution_neural_network.py /^class CNN():$/;" c +Caesar README.md /^### Caesar$/;" S +CeilIndex dynamic_programming/longest_increasing_subsequence_O(nlogn).py /^def CeilIndex(v,l,r,key):$/;" f +Ciphers README.md /^## Ciphers$/;" s +Cocktail shaker README.md /^### Cocktail shaker$/;" S +DEFAULT_BLOCK_SIZE ciphers/rsa_cipher.py /^DEFAULT_BLOCK_SIZE = 128$/;" v +DEFAULT_BUCKET_SIZE sorts/bucket_sort.py /^DEFAULT_BUCKET_SIZE = 5$/;" v +DFS data_structures/graph/depth_first_search.py /^ def DFS(self):$/;" m class:Graph +DFSRec data_structures/graph/depth_first_search.py /^ def DFSRec(self, startVertex, visited):$/;" m class:Graph +DISTANCE searches/test_tabu_search.py /^DISTANCE = 105$/;" v +Decision_Tree machine_learning/decision_tree.py /^class Decision_Tree:$/;" c +DenseLayer neural_network/bpnn.py /^class DenseLayer():$/;" c +Dijkstra data_structures/graph/dijkstra.py /^def Dijkstra(graph, V, src):$/;" f +Documentation linear_algebra_python/README.md /^## Documentation $/;" s +DoubleHash data_structures/hashing/double_hash.py /^class DoubleHash(HashTable):$/;" c +E data_structures/graph/bellman_ford.py /^E = int(raw_input("Enter number of edges: "))$/;" v +E data_structures/graph/dijkstra.py /^E = int(raw_input("Enter number of edges: "))$/;" v +E data_structures/graph/floyd_warshall.py /^E = int(raw_input("Enter number of edges: "))$/;" v +ENGLISH_WORDS other/detecting_english_programmatically.py /^ENGLISH_WORDS = loadDictionary()$/;" v +ETAOIN other/frequency_finder.py /^ETAOIN = 'ETAOINSHRDLCUMWFGYPBVKJXQZ'$/;" v +EditDistance dynamic_programming/edit_distance.py /^class EditDistance:$/;" c +ExternalSort sorts/external-sort.py /^class ExternalSort(object):$/;" c +F dynamic_programming/knapsack.py /^ F = [[0]*(w + 1)] + [[0] + [-1 for i in range(w + 1)] for j in range(n + 1)]$/;" v +FIRST_SOLUTION searches/test_tabu_search.py /^FIRST_SOLUTION = ['a', 'c', 'b', 'd', 'e', 'a']$/;" v +FYshuffle other/Fischer-Yates_Shuffle.py /^def FYshuffle(LIST):$/;" f +FenwickTree data_structures/binary tree/FenwickTree.py /^class FenwickTree:$/;" c +Fibonacci dynamic_programming/fibonacci.py /^class Fibonacci:$/;" c +FileMerger sorts/external-sort.py /^class FileMerger(object):$/;" c +FileSplitter sorts/external-sort.py /^class FileSplitter(object):$/;" c +FilesArray sorts/external-sort.py /^class FilesArray(object):$/;" c +FloydWarshall data_structures/graph/floyd_warshall.py /^def FloydWarshall(graph, V):$/;" f +FordFulkerson networking_flow/Ford_Fulkerson.py /^def FordFulkerson(graph, source, sink):$/;" f +Graph data_structures/graph/breadth_first_search.py /^class Graph():$/;" c +Graph data_structures/graph/depth_first_search.py /^class Graph():$/;" c +Graph data_structures/graph/dijkstra_algorithm.py /^class Graph:$/;" c +Graph data_structures/graph/graph_list.py /^class Graph:$/;" c +Graph data_structures/graph/graph_matrix.py /^class Graph:$/;" c +Graph dynamic_programming/floyd_warshall.py /^class Graph:$/;" c +HOST simple_client_server/client.py /^HOST, PORT = '127.0.0.1', 1400$/;" v +HOST simple_client_server/server.py /^HOST, PORT = '127.0.0.1', 1400$/;" v +HashTable data_structures/hashing/hash_table.py /^class HashTable:$/;" c +HashTableWithLinkedList data_structures/hashing/hash_table_with_linked_list.py /^class HashTableWithLinkedList(HashTable):$/;" c +Heap README.md /^### Heap$/;" S +Heap data_structures/heap/heap.py /^class Heap:$/;" c +InPreOrder data_structures/binary tree/binary_search_tree.py /^def InPreOrder(curr_node):$/;" f +Insertion README.md /^### Insertion$/;" S +Interpolation README.md /^## Interpolation$/;" s +Jump Search README.md /^## Jump Search$/;" s +K hashes/chaos_machine.py /^K = [0.33, 0.44, 0.55, 0.44, 0.33]; t = 3; m = 5$/;" v +L arithmetic_analysis/lu_decomposition.py /^L,U = LUDecompose(matrix)$/;" v +LEARNING_RATE machine_learning/gradient_descent.py /^LEARNING_RATE = 0.009$/;" v +LETTERS ciphers/simple_substitution_cipher.py /^LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'$/;" v +LETTERS ciphers/vigenere_cipher.py /^LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'$/;" v +LETTERS other/frequency_finder.py /^LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'$/;" v +LETTERS_AND_SPACE other/detecting_english_programmatically.py /^LETTERS_AND_SPACE = UPPERLETTERS + UPPERLETTERS.lower() + ' \\t\\n'$/;" v +LUDecompose arithmetic_analysis/lu_decomposition.py /^def LUDecompose (table):$/;" f +Linear README.md /^### Linear$/;" S +Linear algebra library for Python linear_algebra_python/README.md /^# Linear algebra library for Python $/;" c +LinearCongruentialGenerator other/LinearCongruentialGenerator.py /^class LinearCongruentialGenerator(object):$/;" c +Link data_structures/linked_list/DoublyLinkedList.py /^class Link:$/;" c +LinkedList data_structures/linked_list/DoublyLinkedList.py /^class LinkedList:$/;" c +LinkedList data_structures/linked_list/__init__.py /^class LinkedList:$/;" c +Linked_List data_structures/linked_list/singly_LinkedList.py /^class Linked_List:$/;" c +LongestIncreasingSubsequenceLength dynamic_programming/longest_increasing_subsequence_O(nlogn).py /^def LongestIncreasingSubsequenceLength(v):$/;" f +M sorts/random_normaldistribution_quicksort.py /^M = np.load(outfile)$/;" v +MF_knapsack dynamic_programming/knapsack.py /^def MF_knapsack(i,wt,val,j):$/;" f +Matrix linear_algebra_python/src/lib.py /^class Matrix(object):$/;" c +MatrixChainOrder dynamic_programming/matrix_chain_order.py /^def MatrixChainOrder(array):$/;" f +Merge README.md /^### Merge$/;" S +N data_structures/binary tree/LazySegmentTree.py /^ N = 15$/;" v +N data_structures/binary tree/SegmentTree.py /^ N = 15$/;" v +N project_euler/Problem 09/sol2.py /^N = int(raw_input())$/;" v +NEIGHBOURHOOD_OF_SOLUTIONS searches/test_tabu_search.py /^NEIGHBOURHOOD_OF_SOLUTIONS = [['a', 'e', 'b', 'd', 'c', 'a', 90],$/;" v +NEIGHBOURS_DICT searches/test_tabu_search.py /^NEIGHBOURS_DICT = {'a': [['b', '20'], ['c', '18'], ['d', '22'], ['e', '26']],$/;" v +NWayMerge sorts/external-sort.py /^class NWayMerge(object):$/;" c +NewtonRaphson arithmetic_analysis/newton_raphson_method.py /^def NewtonRaphson(func, a):$/;" f +Node data_structures/avl.py /^class Node:$/;" c +Node data_structures/binary tree/binary_search_tree.py /^class Node:$/;" c +Node data_structures/linked_list/__init__.py /^class Node:$/;" c +Node data_structures/linked_list/singly_LinkedList.py /^class Node: # create a Node$/;" c +Normal Distribution QuickSort sorts/normal_distribution_QuickSort_README.md /^# Normal Distribution QuickSort$/;" c +Note: simple_client_server/README.md /^#### Note:$/;" t +Onepad ciphers/onepad_cipher.py /^class Onepad:$/;" c +Overview linear_algebra_python/README.md /^## Overview $/;" s +PORT simple_client_server/client.py /^HOST, PORT = '127.0.0.1', 1400$/;" v +PORT simple_client_server/server.py /^HOST, PORT = '127.0.0.1', 1400$/;" v +PROGNAME other/sierpinski_triangle.py /^PROGNAME = 'Sierpinski Triangle'$/;" v +Perceptron machine_learning/perceptron.py /^class Perceptron:$/;" c +Perceptron neural_network/perceptron.py /^class Perceptron:$/;" c +Plotting the function for Checking 'The Number of Comparisons' taking place between Normal Distribution QuickSort and Ordinary QuickSort sorts/normal_distribution_QuickSort_README.md /^## Plotting the function for Checking 'The Number of Comparisons' taking place between Normal Di/;" s +PrimsAlgorithm graphs/MinimumSpanningTree_Prims.py /^def PrimsAlgorithm(l):$/;" f +PrintOptimalSolution dynamic_programming/matrix_chain_order.py /^def PrintOptimalSolution(OptimalSolution,i,j):$/;" f +PriorityQueue data_structures/graph/dijkstra_algorithm.py /^class PriorityQueue:$/;" c +PriorityQueue graphs/Multi_Hueristic_Astar.py /^class PriorityQueue:$/;" c +ProjectEuler project_euler/README.md /^# ProjectEuler$/;" c +QuadraticProbing data_structures/hashing/__init__.py /^class QuadraticProbing(HashTable):$/;" c +QuadraticProbing data_structures/hashing/quadratic_probing.py /^class QuadraticProbing(HashTable):$/;" c +Queue data_structures/queue/QueueOnList.py /^class Queue():$/;" c +Queue data_structures/queue/QueueOnPseudoStack.py /^class Queue():$/;" c +Quick README.md /^### Quick$/;" S +Quick Select README.md /^## Quick Select$/;" s +ROT13 README.md /^## ROT13$/;" s +RSA (Rivest–Shamir–Adleman) README.md /^### RSA (Rivest–Shamir–Adleman)$/;" S +Radix README.md /^### Radix$/;" S +ReadModel neural_network/convolution_neural_network.py /^ def ReadModel(cls,model_path):$/;" m class:CNN +ReceiveFile file_transfer_protocol/ftp_send_receive.py /^def ReceiveFile():$/;" f +Representational analysis/Compression_Analysis/PSNR.py /^def Representational(r,g,b):$/;" f +S data_structures/stacks/Stock-Span-Problem.py /^S = [0 for i in range(len(price)+1)] $/;" v +S1 dynamic_programming/edit_distance.py /^ S1 = raw_input().strip()$/;" v +S2 dynamic_programming/edit_distance.py /^ S2 = raw_input().strip()$/;" v +SHA1Hash hashes/sha1.py /^class SHA1Hash:$/;" c +SHA1HashTest hashes/sha1.py /^class SHA1HashTest(unittest.TestCase):$/;" c +SOE other/FindingPrimes.py /^def SOE(n):$/;" f +SYMBOLS ciphers/affine_cipher.py /^SYMBOLS = """ !"#$%&'()*+,-.\/0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnop/;" v +Search Algorithms README.md /^## Search Algorithms$/;" s +SegmentTree data_structures/binary tree/LazySegmentTree.py /^class SegmentTree:$/;" c +SegmentTree data_structures/binary tree/SegmentTree.py /^class SegmentTree:$/;" c +Selection README.md /^### Selection$/;" S +SendFile file_transfer_protocol/ftp_send_receive.py /^def SendFile():$/;" f +Shell README.md /^### Shell$/;" S +Sort Algorithms README.md /^## Sort Algorithms$/;" s +Source: [Wikipedia](https://en.wikipedia.org/wiki/Caesar_cipher) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/Caesar_cipher)$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/Interpolation_search) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/Interpolation_search)$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/Jump_search) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/Jump_search)$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/Quickselect) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/Quickselect)$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/ROT13) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/ROT13)$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/RSA_(cryptosystem))$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/Tabu_search) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/Tabu_search)$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/Transposition_cipher) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/Transposition_cipher)$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/Vigen%C3%A8re_cipher)$/;" u +Source: [Wikipedia](https://en.wikipedia.org/wiki/XOR_cipher) README.md /^###### Source: [Wikipedia](https:\/\/en.wikipedia.org\/wiki\/XOR_cipher)$/;" u +Stack data_structures/stacks/__init__.py /^class Stack:$/;" c +Stack data_structures/stacks/stack.py /^class Stack(object):$/;" c +StackOverflowError data_structures/stacks/stack.py /^class StackOverflowError(BaseException):$/;" c +SubArray dynamic_programming/longest_sub_array.py /^class SubArray:$/;" c +T project_euler/Problem 02/sol2.py /^T = int(input().strip())$/;" v +TAG machine_learning/k_means_clust.py /^TAG = 'K-MEANS-CLUST\/ '$/;" v +TEST_FILE searches/test_tabu_search.py /^TEST_FILE = os.path.join(os.path.dirname(__file__), '.\/tabuTestData.txt')$/;" v +TFKMeansCluster dynamic_programming/k_means_clustering_tensorflow.py /^def TFKMeansCluster(vectors, noofclusters):$/;" f +Tabu README.md /^## Tabu$/;" s +Test linear_algebra_python/src/tests.py /^class Test(unittest.TestCase):$/;" c +TestClass searches/test_tabu_search.py /^class TestClass(unittest.TestCase):$/;" c +TestUnionFind data_structures/union_find/tests_union_find.py /^class TestUnionFind(unittest.TestCase):$/;" c +Tests linear_algebra_python/README.md /^## Tests $/;" s +The Algorithms - Python README.md /^# The Algorithms - Python