<commit_before>//
//  HackerRankHelper.swift
//  HRSwift
//
//  Created by <NAME> on 2015-11-20.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import Foundation

/**
    This document may contain code that use swift1.2 since HackerRank only support swift1.2
 
    But if possible I could write some swift2.* code and I will annotate them.
 
*/
 
// MARK: Basic Text/File Operations

/**
    HackerRank GetLine
    
    - Returns: String from stdin
*/

public func getLine() -> String {
    var buf = String()
    var c = getchar()
    // 10 is the ascii code for new line
    while c != EOF && c != 10 {
        buf.append(UnicodeScalar(UInt32(c)))
        c = getchar()
    }
    return buf
}

public func getInt() -> Int {
    return Int(getLine())!
}

public func getLineToArray() -> [String] {
    let currentLine = getLine()
    let retVal = currentLine.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    return retVal.filter { Int($0) != nil }
}

/**
 *  reading into n lines and combine them into an Array
 *  
 *  - parameter n: number of lines you want to read in
 */
public func getLinesToArray(n: Int) -> [String] {
    var retVal: [String] = []
    for _ in 0..<n {
        retVal.append(getLine())
    }
    return retVal
}

/** Class for reading data from files
 *  Reference: http://stackoverflow.com/questions/24581517/read-a-file-url-line-by-line-in-swift/24648951#24648951
 */
class StreamReader {
    // Encoding used by data
    let encoding: UInt
    let chunkSize: Int
    
    let dataBuffer: NSMutableData!
    let fileHandle: NSFileHandle!
    let delimData: NSData!
    
    var atEof: Bool = false
    
    init?(path: String, delimiter: String = "\n", encoding: UInt = NSUTF8StringEncoding, chunkSize: Int = 4096) {
        self.encoding = encoding
        self.chunkSize = chunkSize
        
        if let fileHandle = NSFileHandle(forReadingAtPath: path), delimData = delimiter.dataUsingEncoding(encoding), dataBuffer = NSMutableData(capacity: chunkSize)  {
            self.fileHandle = fileHandle
            self.delimData = delimData
            self.dataBuffer = dataBuffer
        } else {
            self.fileHandle = nil
            self.delimData = nil
            self.dataBuffer = nil
            return nil
        }
    }
    
    deinit {
        self.close()
    }
    
    func nextLine() -> String? {
        precondition(fileHandle != nil, "Attempt to read from closed file")
        
        if atEof {
            return nil
        }
        
        var range = dataBuffer.rangeOfData(delimData, options: [], range: NSMakeRange(0, dataBuffer.length))
        while range.location == NSNotFound {
            let tmpData = fileHandle.readDataOfLength(chunkSize)
            if tmpData.length == 0 {
                // EOF or error
                atEof = true
                if dataBuffer.length > 0 {
                    let retVal = NSString(data: dataBuffer, encoding: encoding)
                    dataBuffer.length = 0
                    return retVal as String?
                }
                return nil
            }
            dataBuffer.appendData(tmpData)
            range = dataBuffer.rangeOfData(delimData, options: [], range: NSMakeRange(0, dataBuffer.length))
        }
        
        let retVal = NSString(data: dataBuffer.subdataWithRange(NSMakeRange(0, range.location)), encoding: encoding)
        dataBuffer.replaceBytesInRange(NSMakeRange(0, range.location + range.length), withBytes: nil, length: 0)
        return retVal as String?
    }
    
    func rewind() -> Void {
        self.fileHandle.seekToFileOffset(0)
        dataBuffer.length = 0
        atEof = false
    }
    
    func close() -> Void {
        self.fileHandle.closeFile()
    }
}


// MARK: Tool Functions
/**
    Get all primes up to length
    
    - parameter length: the upper boundary for primes
    - returns : an array of all primes in that range
*/
public func getBetterPrimes(length:Int) -> [Int] {
    // Here the length means how many elements we have<commit_msg>Added Public Modifier<commit_after>//
//  HackerRankHelper.swift
//  HRSwift
//
//  Created by <NAME> on 2015-11-20.
//  Copyright © 2015 <NAME>. All rights reserved.
//

import Foundation

/**
    This document may contain code that use swift1.2 since HackerRank only support swift1.2
 
    But if possible I could write some swift2.* code and I will annotate them.
 
*/
 
// MARK: Basic Text/File Operations

/**
    HackerRank GetLine
    
    - Returns: String from stdin
*/

public func getLine() -> String {
    var buf = String()
    var c = getchar()
    // 10 is the ascii code for new line
    while c != EOF && c != 10 {
        buf.append(UnicodeScalar(UInt32(c)))
        c = getchar()
    }
    return buf
}

public func getInt() -> Int {
    return Int(getLine())!
}

public func getLineToArray() -> [String] {
    let currentLine = getLine()
    let retVal = currentLine.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    return retVal.filter { Int($0) != nil }
}

/**
 *  reading into n lines and combine them into an Array
 *  
 *  - parameter n: number of lines you want to read in
 */
public func getLinesToArray(n: Int) -> [String] {
    var retVal: [String] = []
    for _ in 0..<n {
        retVal.append(getLine())
    }
    return retVal
}

/** Class for reading data from files
 *  Reference: http://stackoverflow.com/questions/24581517/read-a-file-url-line-by-line-in-swift/24648951#24648951
 */
public class StreamReader {
    // Encoding used by data
    let encoding: UInt
    let chunkSize: Int
    
    let dataBuffer: NSMutableData!
    let fileHandle: NSFileHandle!
    let delimData: NSData!
    
    var atEof: Bool = false
    
    public init?(path: String, delimiter: String = "\n", encoding: UInt = NSUTF8StringEncoding, chunkSize: Int = 4096) {
        self.encoding = encoding
        self.chunkSize = chunkSize
        
        if let fileHandle = NSFileHandle(forReadingAtPath: path), delimData = delimiter.dataUsingEncoding(encoding), dataBuffer = NSMutableData(capacity: chunkSize)  {
            self.fileHandle = fileHandle
            self.delimData = delimData
            self.dataBuffer = dataBuffer
        } else {
            self.fileHandle = nil
            self.delimData = nil
            self.dataBuffer = nil
            return nil
        }
    }
    
    deinit {
        self.close()
    }
    
    public func nextLine() -> String? {
        precondition(fileHandle != nil, "Attempt to read from closed file")
        
        if atEof {
            return nil
        }
        
        var range = dataBuffer.rangeOfData(delimData, options: [], range: NSMakeRange(0, dataBuffer.length))
        while range.location == NSNotFound {
            let tmpData = fileHandle.readDataOfLength(chunkSize)
            if tmpData.length == 0 {
                // EOF or error
                atEof = true
                if dataBuffer.length > 0 {
                    let retVal = NSString(data: dataBuffer, encoding: encoding)
                    dataBuffer.length = 0
                    return retVal as String?
                }
                return nil
            }
            dataBuffer.appendData(tmpData)
            range = dataBuffer.rangeOfData(delimData, options: [], range: NSMakeRange(0, dataBuffer.length))
        }
        
        let retVal = NSString(data: dataBuffer.subdataWithRange(NSMakeRange(0, range.location)), encoding: encoding)
        dataBuffer.replaceBytesInRange(NSMakeRange(0, range.location + range.length), withBytes: nil, length: 0)
        return retVal as String?
    }
    
    public func rewind() -> Void {
        self.fileHandle.seekToFileOffset(0)
        dataBuffer.length = 0
        atEof = false
    }
    
    public func close() -> Void {
        self.fileHandle.closeFile()
    }
}


// MARK: Tool Functions
/**
    Get all primes up to length
    
    - parameter length: the upper boundary for primes
    - returns : an array of all primes in that range
*/
public func getBetterPrimes(length:Int) -> [Int] {
    // Here the length means how many elements we have
{'fraction_non_alphanumeric': 0.09688834655277609, 'fraction_numerical': 0.01561928004881025, 'mean_word_length': 2.113981762917933, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2988259', 'n_tokens_mistral': 2499, 'n_tokens_neox': 2336, 'n_words': 684}