Ninety-Nine Scala Problems 不错的scala入门练习题

不错的scala入门练习题。
原站网址:http://wiki.summercode.com/s_99_ninety_nine_scala_problems
P01 (*) Find the last element of a list.
Example:
scala> last(List(1, 1, 2, 3, 5, 8))
res0: Int = 8

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(1,2,3,4,5,6)
println(last(a))
println(last_1(a))
}

def last(lst : List[Int]):Int={
    if(lst.length==1) lst.head
    else last(lst.tail)
}
def last_1(lst:List[Int]):Int={
    val lst1=lst.reverse
    lst1.head
}

}

P02 (*) Find the last but one element of a list.
Example:
scala> penultimate(List(1, 1, 2, 3, 5, 8))
res0: Int = 5

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(1,2,3,4,5,6)
println(penultimate(a))
println(penultimate_1(a))
}
def penultimate(lst : List[Int]):Int={
if(lst.length==2) lst.head
else penultimate(lst.tail)
}
def penultimate_1(lst:List[Int]):Int={
val lst1=lst.reverse
val lst_t=lst1.tail
lst_t.head
}
}

P03 (*) Find the Kth element of a list.
By convention, the first element in the list is element 0.
Example:
scala> nth(2, List(1, 1, 2, 3, 5, 8))
res0: Int = 2

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(1,1,2,3,5,8)
println(nth(8,a))
}
var K=0
def nth(n:Int,lst:List[Int]):Int={
if(lst==Nil) return 10000
if(lst.head==n) return K
else{
K+=1
nth(n,lst.tail)
}
}
def nth_1(n:Int,xs:List[Int]):Int={
def nthR(c:Int,xs:List[Int]):Int=(c,xs)match{
case (_,Nil)=>10000
case (1,h::tail)=>h
case (_,h::tail)=>nthR(c-1,tail)
}
nthR(n,xs)
}
}

P04 (*) Find the number of elements of a list.
Example:
scala> length(List(1, 1, 2, 3, 5, 8))
res0: Int = 6

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(1,1,2,3,5,8)
println(length_1(a))
}
var len=0
def length(lst:List[Int]):Int={
if(lst==Nil) return len
else {len+=1;length(lst.tail)}
}
def length_1(lst:List[Int]):Int=lst match {
case Nil =>len
case h::t =>{len+=1;length_1(t)}
}
def length_2(xs:List[Int]):Int={
def lenR(c:Int,xs:List[Int]):Int=(c,xs)match{
case (_,Nil)=>c
case (_,h::tail)=>lenR(c+1,tail)
}
var res=0
lenR(res,xs)
}
}

P05 (*) Reverse a list.
Example:
scala> reverse(List(1, 1, 2, 3, 5, 8))
res0: List[Int] = List(8, 5, 3, 2, 1, 1)

object App{
def main(args:Array[String]){
val ls=List(5,4,3,2,1,0)
val b=List(‘a, ‘b, ‘c, ‘c, ‘d)
println(reverse_1(ls))
}
def reverse(xs:List[Int]):List[Int]=xs match{
case Nil=>Nil
case x::xsl=>reverse(xsl):::List(x)
}
def reverse_1A:List[A]={
xs.foldLeft(List.empty[A]) { (r,h) => h :: r }
}
def reverseFunctional[A](ls: List[A]): List[A] =
ls.foldLeft(ListA) { (r, h) => h :: r }
}

P06 (*) Find out whether a list is a palindrome.
Example:
scala> isPalindrome(List(1, 2, 3, 2, 1))
res0: Boolean = true

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(1, 2, 3, 2, 1)
println(isPalindrome(a))
}
def isPalindrome(lst:List[Int]):Boolean={
var tmp=lst.reverse
val it1=Iterator(lst)
val it2=Iterator(tmp)
while(it1.hasNext){
if(it1.next()!=it2.next()) return false
}
true
}
}

P07 (**) Flatten a nested list structure.
Example:
scala> flatten(List(List(1, 1), 2, List(3, List(5, 8))))
res0: List[Any] = List(1, 1, 2, 3, 5, 8)

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(List(1, 1), 2, List(3, List(5, 8)))
println(flatten(a))
}
def flatten(lst:List[Any]):List[Any]=lst flatMap{
case a: List[_] => flatten(a)
case b => List(b)
}
}

P08 (**) Eliminate consecutive duplicates of list elements.
If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
Example:
scala> compress(List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e))
res0: List[Symbol] = List(‘a, ‘b, ‘c, ‘a, ‘d, ‘e)

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(‘a’, ‘a’, ‘a’, ‘a’, ‘b’, ‘c’, ‘c’, ‘a’, ‘a’, ‘d’, ‘e’, ‘e’, ‘e’, ‘e’)
println(compress(a))
}

  def compress(ls: List[Char]): List[Char] = ls match {
    case Nil       => Nil
    case h :: tail =>{h::tail.dropWhile(_ == h)}
  }

def compressA:List[A]={
def compRA:List[A]=(c,xs)match{
case (_,Nil)=>Nil
case (c,h::tail)=>{if(c==h) compR(c,tail) else h::compR(h,tail)}
}
xs.head::compR(xs.head,xs)
}

  // Functional.
  def compress_1(ls: List[Char]): List[Char] =
    ls.foldRight(List[Char]()) { (h, r) =>
      if (r.isEmpty || r.head != h) h :: r
      else r
    }

}

P09 (**) Pack consecutive duplicates of list elements into sublists.
If a list contains repeated elements they should be placed in separate sublists.
Example:
scala> pack(List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e))
res0: List[List[Symbol]] = List(List(‘a, ‘a, ‘a, ‘a), List(‘b), List(‘c, ‘c), List(‘a, ‘a), List(‘d), List(‘e, ‘e, ‘e, ‘e))
import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e)
pack(a)
}
def packA:List[List[A]]={
if(ls.isEmpty) List(List())
else{
val (packed,next)=ls span{_ ==ls.head}
if(next==Nil) {List(packed)}
else {println(“next”+” “+next);println(packed);packed::pack(next)}
}
}
}

    def pack[A](xs:List[A]):List[List[A]]={
        if(xs.isEmpty) List[List[A]]()
        else{
            val (packed,next)=xs span(_ ==xs.head)
            if(next==Nil) List(packed)
            else packed::pack(next) 
        }
    }

P10 (*) Run-length encoding of a list.
Use the result of problem P09 to implement the so-called run-length encoding data compression method. Consecutive duplicates of elements are encoded as tuples (N, E) where N is the number of duplicates of the element E.
Example:
scala> encode(List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e))
res0: List[(Int, Symbol)] = List((4,’a), (1,’b), (2,’c), (2,’a), (1,’d), (4,’e))

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e)
println(encode(a))
}

    def encode[A](xs:List[A]):List[(A,Int)]={
        def pack[A](xs:List[A]):List[List[A]]={
        if(xs.isEmpty) List[List[A]]()
        else{
            val (packed,next)=xs span(_ ==xs.head)
            if(next==Nil) List(packed)
            else packed::pack(next) 
            }
        }
        pack(xs).map(e=>(e.head,e.length))
    }       

}

P11 (*) Modified run-length encoding.
Modify the result of problem P10 in such a way that if an element has no duplicates it is simply copied into the result list. Only elements with duplicates are transferred as (N, E) terms.
Example:
scala> encodeModified(List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e))
res0: List[Any] = List((4,’a), ‘b, (2,’c), (2,’a), ‘d, (4,’e))

import scala.collection.mutable._
object App
{
def main(args:Array[String]){
val a=List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e)
println(encodeModified(a))
}

def encodeModifiedA:List[Any]={
def packA:List[List[A]]={
if(xs.isEmpty) ListList[A]
else{
val (packed,next)=xs span(_ ==xs.head)
if(next==Nil) List(packed)
else packed::pack(next)
}
}
pack(xs).map(e=>(e.head,e.length)).map(e=>if(e._2==1) e._1 else e )
}
}

P12 (**) Decode a run-length encoded list.
Given a run-length code list generated as specified in problem P10, construct its uncompressed version.
Example:
scala> decode(List((4, ‘a), (1, ‘b), (2, ‘c), (2, ‘a), (1, ‘d), (4, ‘e)))
res0: List[Symbol] = List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e)

    def encode[A](xs:List[(Int,A)]):List[A]={
        val (num,char)=xs.unzip
        var res=List[A]()
        for(i<- 0 to num.length-1){
            for(j<- 1 to num(i)){
                res=char(i)::res
            }
        }
        res.reverse
    }

P13 (**) Run-length encoding of a list (direct solution).
Implement the so-called run-length encoding data compression method directly. I.e. don’t use other methods you’ve written (like P09’s pack); do all the work directly.
Example:
scala> encodeDirect(List(‘a, ‘a, ‘a, ‘a, ‘b, ‘c, ‘c, ‘a, ‘a, ‘d, ‘e, ‘e, ‘e, ‘e))
res0: List[(Int, Symbol)] = List((4,’a), (1,’b), (2,’c), (2,’a), (1,’d), (4,’e))

def main(args:Array[String]){
    val ls=List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)
    print(encodeDirect(ls))
}
def encodeDirect[A](xs:List[A]):List[(Int,A)]=
    if(xs.isEmpty) Nil
    else {
        val (f,l)=xs span( _ == xs.head)
        (f.length,f.head)::encodeDirect(l)
    }           

}
P14 (*) Duplicate the elements of a list.
Example:
scala> duplicate(List(‘a, ‘b, ‘c, ‘c, ‘d))
res0: List[Symbol] = List(‘a, ‘a, ‘b, ‘b, ‘c, ‘c, ‘c, ‘c, ‘d, ‘d)

object App{
def main(args:Array[String]){
val ls=List(‘a, ‘b, ‘c, ‘c, ‘d)
val words=List(“the”,”quick”,”brown”,”fox”)
var res=words dropWhile(_ startsWith “t”)
println(duplicate(ls))
}
def duplicateA:List[A]=xs match {
case Nil =>Nil
case h::tail=>h::h::duplicate(tail)
}
}

P15 (**) Duplicate the elements of a list a given number of times.
Example:
scala> duplicateN(3, List(‘a, ‘b, ‘c, ‘c, ‘d))
res0: List[Symbol] = List(‘a, ‘a, ‘a, ‘b, ‘b, ‘b, ‘c, ‘c, ‘c, ‘c, ‘c, ‘c, ‘d, ‘d, ‘d)

object App{
def main(args:Array[String]){
val ls=List(‘a, ‘b, ‘c, ‘c, ‘d)
val words=List(“the”,”quick”,”brown”,”fox”)
var res=words dropWhile(_ startsWith “t”)
println(duplicateN(5,ls))
}
def duplicateNA:List[A]=xs match {
case Nil =>Nil
case h::tail=>{
var tmp=ListA
for(i <- 1 to n){ tmp=h::tmp }
tmp:::duplicateN(n,tail)
}
}
}

P16 (**) Drop every Nth element from a list.
Example:
scala> drop(3, List(‘a, ‘b, ‘c, ‘d, ‘e, ‘f, ‘g, ‘h, ‘i, ‘j, ‘k))
res0: List[Symbol] = List(‘a, ‘b, ‘d, ‘e, ‘g, ‘h, ‘j, ‘k)

object App{
def main(args:Array[String]){
val ls=List(‘a, ‘b, ‘c, ‘d, ‘e, ‘f, ‘g, ‘h, ‘i, ‘j, ‘k)
println(drop(3,ls))
}

    def drop[A](n:Int,xs:List[A]):List[A]={
        def dropR[A](c:Int,xs:List[A]):List[A]=(c,xs)match{
        case ( _ , Nil) =>Nil
        case ( 1 , h :: tail)=> dropR(n,tail)
        case ( _ , h :: tail) =>h::dropR(c-1,tail)
        }
        dropR(n,xs)
    }

}

P17 (*) Split a list into two parts.
The length of the first part is given. Use a Tuple for your result.
Example:
scala> split(3, List(‘a, ‘b, ‘c, ‘d, ‘e, ‘f, ‘g, ‘h, ‘i, ‘j, ‘k))
res0: (List[Symbol], List[Symbol]) = (List(‘a, ‘b, ‘c),List(‘d, ‘e, ‘f, ‘g, ‘h, ‘i, ‘j, ‘k))

    def splitFunctional[A](n: Int, ls: List[A]): (List[A], List[A]) =
        (ls.take(n), ls.drop(n))

    def split[A](n:Int,xs:List[A]):(List[A],List[A])={
        def splitR(n:Int,xs:List[A]):(List[A],List[A])=(n,xs) match {
            case (_,Nil) =>(Nil,Nil)
            case (0,list)=>(Nil,list)
            case (n,h::tail)=>{
                val (fls,lls)=splitR(n-1,tail)
                (h::fls,lls)
            } 
        }   
        splitR(n,xs)
    }

P18 (**) Extract a slice from a list.
Given two indices, I and K, the slice is the list containing the elements from and including the Ith element up to but not including the Kth element of the original list. Start counting the elements with 0.
Example:
scala> slice(3, 7, List(‘a, ‘b, ‘c, ‘d, ‘e, ‘f, ‘g, ‘h, ‘i, ‘j, ‘k))
res0: List[Symbol] = List(‘d, ‘e, ‘f, ‘g)

    def slice[A](x:Int,y:Int,xs:List[A]):List[A]={
        return xs.drop(x).take(y-x)
    }

def slice_1[A](x:Int,y:Int,xs:List[A]):List[A]={
    def sliceR[A](x:Int,y:Int,xs:List[A]):List[A]=(x,y,xs) match {
            case (_,_,Nil) =>Nil
            case (0,y,list)=>xs.take(y)
            case (x,0,list)=>Nil
            case (x,y,h::tail)=>sliceR(x-1,y-1,tail) 
        }
        sliceR(x,y,xs)
    }

P19 (**) Rotate a list N places to the left.
Examples:
scala> rotate(3, List(‘a, ‘b, ‘c, ‘d, ‘e, ‘f, ‘g, ‘h, ‘i, ‘j, ‘k))
res0: List[Symbol] = List(‘d, ‘e, ‘f, ‘g, ‘h, ‘i, ‘j, ‘k, ‘a, ‘b, ‘c)

scala> rotate(-2, List(‘a, ‘b, ‘c, ‘d, ‘e, ‘f, ‘g, ‘h, ‘i, ‘j, ‘k))
res1: List[Symbol] = List(‘j, ‘k, ‘a, ‘b, ‘c, ‘d, ‘e, ‘f, ‘g, ‘h, ‘i)

def rotateA:List[A]={
val d=if(n>=0) true else false
val c=if(d) n%xs.length else -n%xs.length
def rotateRA:List[A]=(n,xs) match {
case (_,Nil) =>Nil
case (0,list)=>list
case (n,h::tail)=>{if(d) rotateR(n-1,tail:::List(h))
else{
rotateR(n-1,((xs.reverse.head::xs).reverse).tail.reverse)
}
}
}
rotateR(c,xs)
}

P20 (*) Remove the Kth element from a list.
Return the list and the removed element in a Tuple. Elements are numbered from 0.
Example:
scala> removeAt(1, List(‘a, ‘b, ‘c, ‘d))
res0: (List[Symbol], Symbol) = (List(‘a, ‘c, ‘d),’b)

    def removeAt[A](n:Int,xs:List[A]):(List[A],A)={
        (xs.take(n):::xs.drop(n).tail,xs.drop(n).head)
    }

P21 (*) Insert an element at a given position into a list.
Example:
scala> insertAt(‘new, 1, List(‘a, ‘b, ‘c, ‘d))
res0: List[Symbol] = List(‘a, ‘new, ‘b, ‘c, ‘d)

def insertAt[A](a:A,n:Int,xs:List[A]):List[A]={
    xs.take(n):::List(a):::xs.drop(n)

}

P22 (*) Create a list containing all integers within a given range.
Example:
scala> range(4, 9)
res0: List[Int] = List(4, 5, 6, 7, 8, 9)

def range(x:Int, y:Int):List[Int]={
if(x>y) Nil
else x::range(x+1,y)
}

P23 (**) Extract a given number of randomly selected elements from a list.
Example:
scala> randomSelect(3, List(‘a, ‘b, ‘c, ‘d, ‘f, ‘g, ‘h))
res0: List[Symbol] = List(‘e, ‘d, ‘a)
Hint: Use the solution to problem P20
def randomSelectA:List[A]={
def ranRA:List[A]=(n,rand,xs) match{
case (,,Nil)=>Nil
case (0,,)=>Nil
case (n,rand,list)=>{xs.drop(rand).head::ranR(n-1,randomNum(n),xs.take(rand):::xs.drop(rand).tail)}
}
def randomNum(len:Int):Int={
val random=Math.abs(scala.util.Random.nextInt()%len)
random
}
ranR(n,randomNum(xs.length),xs)
}
P24 (*) Lotto: Draw N different random numbers from the set 1..M.
Example:
scala> lotto(6, 49)
res0: List[Int] = List(23, 1, 17, 33, 21, 37)

def lotto_24(n:Int,M:Int):List[Int]={
var res=ArrayInt
def randomNum(M:Int):Int={
val random=Math.abs(scala.util.Random.nextInt()%M)
for(i<-0 to (res.length-1)){
if(res(i)==random) randomNum(M)
}
random
}
for(i<- 1 to n){
res=res:+randomNum(M)
}
val result=res.toList
result
}

P25 (*) Generate a random permutation of the elements of a list.
Hint: Use the solution of problem P23.
Example:
scala> randomPermute(List(‘a, ‘b, ‘c, ‘d, ‘e, ‘f))
res0: List[Symbol] = List(‘b, ‘a, ‘d, ‘c, ‘e, ‘f)

def randomPermute_25[Any](xs: List[Any]): List[Any] = {
        randomSelect_23(xs.length-1,xs)
}

P26 (**) Generate the combinations of K distinct objects chosen from the N elements of a list.
In how many ways can a committee of 3 be chosen from a group of 12 people? We all know that there are C(12,3) = 220 possibilities (C(N,K) denotes the well-known binomial coefficient). For pure mathematicians, this result may be great. But we want to really generate all the possibilities.
Example:
scala> combinations(3, List(‘a, ‘b, ‘c, ‘d, ‘e, ‘f))
res0: List[List[Symbol]] = List(List(‘a, ‘b, ‘c), List(‘a, ‘b, ‘d), List(‘a, ‘b, ‘e), …
P27 (**) Group the elements of a set into disjoint subsets.
a) In how many ways can a group of 9 people work in 3 disjoint subgroups of 2, 3 and 4 persons? Write a function that generates all the possibilities.
Example:
scala> group3(List(“Aldo”, “Beat”, “Carla”, “David”, “Evi”, “Flip”, “Gary”, “Hugo”, “Ida”))
res0: List[List[List[String]]] = List(List(List(Aldo, Beat), List(Carla, David, Evi), List(Flip, Gary, Hugo, Ida)), …
b) Generalize the above predicate in a way that we can specify a list of group sizes and the predicate will return a list of groups.
Example:
scala> group(List(2, 2, 5), List(“Aldo”, “Beat”, “Carla”, “David”, “Evi”, “Flip”, “Gary”, “Hugo”, “Ida”))
res0: List[List[List[String]]] = List(List(List(Aldo, Beat), List(Carla, David), List(Evi, Flip, Gary, Hugo, Ida)), …
Note that we do not want permutations of the group members; i.e. ((Aldo, Beat), …) is the same solution as ((Beat, Aldo), …). However, we make a difference between ((Aldo, Beat), (Carla, David), …) and ((Carla, David), (Aldo, Beat), …).
You may find more about this combinatorial problem in a good book on discrete mathematics under the term “multinomial coefficients”.
P28 (**) Sorting a list of lists according to length of sublists.
a) We suppose that a list contains elements that are lists themselves. The objective is to sort the elements of the list according to their length. E.g. short lists first, longer lists later, or vice versa.
Example:
scala> lsort(List(List(‘a, ‘b, ‘c), List(‘d, ‘e), List(‘f, ‘g, ‘h), List(‘d, ‘e), List(‘i, ‘j, ‘k, ‘l), List(‘m, ‘n), List(‘o)))
res0: List[List[Symbol]] = List(List(‘o), List(‘d, ‘e), List(‘d, ‘e), List(‘m, ‘n), List(‘a, ‘b, ‘c), List(‘f, ‘g, ‘h), List(‘i, ‘j, ‘k, ‘l))
b) Again, we suppose that a list contains elements that are lists themselves. But this time the objective is to sort the elements according to their length frequency; i.e. in the default, sorting is done ascendingly, lists with rare lengths are placed, others with a more frequent length come later.
Example:
scala> lsortFreq(List(List(‘a, ‘b, ‘c), List(‘d, ‘e), List(‘f, ‘g, ‘h), List(‘d, ‘e), List(‘i, ‘j, ‘k, ‘l), List(‘m, ‘n), List(‘o)))
res1: List[List[Symbol]] = List(List(‘i, ‘j, ‘k, ‘l), List(‘o), List(‘a, ‘b, ‘c), List(‘f, ‘g, ‘h), List(‘d, ‘e), List(‘d, ‘e), List(‘m, ‘n))
Note that in the above example, the first two lists in the result have length 4 and 1 and both lengths appear just once. The third and fourth lists have length 3 and there are two list of this length. Finally, the last three lists have length 2. This is the most frequent length.
Arithmetic
For the next section, we’re going to take a different tack with the solutions. We’ll declare a new class, S99Int, and an implicit conversion from regular Ints. The arithmetic1 file contains the starting definitions for this section. Each individual solution will show the relevant additions to the S99Int class. The full class will be given at the end of the section.
P31 (**) Determine whether a given integer number is prime.
scala> 7.isPrime
res0: Boolean = true
def isPrime(start:Int): Boolean ={
if (start<=1) return false
val res=2 to start takeWhile{_<=Math.sqrt(start)}
res.forall{start % _ != 0}
}

P32 (**) Determine the greatest common divisor of two positive integer numbers.
Use Euclid’s algorithm.
scala> gcd(36, 63)
res0: Int = 9

    def gcd_32(a:Int,b:Int):Int={
        if(a%b==0) return b
        else gcd_32(b,a%b)
    }

P33 (*) Determine whether two positive integer numbers are coprime.
Two numbers are coprime if their greatest common divisor equals 1.
scala> 35.isCoprimeTo(64)
res0: Boolean = true

    def isCoprimeTo_33(x:Int,y:Int):Boolean={
        def gcd(a:Int,b:Int):Int={
            if(a%b==0) return b
            else gcd_32(b,a%b)
        }
        if(gcd(x,y)==1) true else false
    }

P34 (**) Calculate Euler’s totient function phi(m).
Euler’s so-called totient function phi(m) is defined as the number of positive integers r (1 <= r <= m) that are coprime to m.
scala> 10.totient
res0: Int = 4

    def totient_34(x:Int):Int={
        var count=0
        for(i <- 1 to x){
            if(isCoprimeTo_33(i,x)) count+=1
        }
        count
    }

P35 (**) Determine the prime factors of a given positive integer.
Construct a flat list containing the prime factors in ascending order.
scala> 315.primeFactors
res0: List[Int] = List(3, 3, 5, 7)

    import scala.collection.mutable._
    def primeFactors(x:Int):ArrayBuffer[Int]={
        var res=ArrayBuffer[Int]()
        var m=x
        val mid=if(Math.sqrt(m).toInt>x/2)Math.sqrt(m) else x/2
        var i=2
        while(i<=mid && m!=1 ){
            if(m%i==0 && isPrime(i)){
                 res+=i;m=m/i;i=1;
            }
            i+=1
       }
       res
    }

P36 (**) Determine the prime factors of a given positive integer (2).
Construct a list containing the prime factors and their multiplicity.
scala> 315.primeFactorMultiplicity
res0: List[(Int, Int)] = List((3,2), (5,1), (7,1))
Alternately, use a Map for the result.
scala> 315.primeFactorMultiplicity
res0: Map[Int,Int] = Map(3 -> 2, 5 -> 1, 7 -> 1)

    def primeFactorMultiplicity_36(x:Int):List[(Int,Int)]={
        var arr=primeFactors_35(x)
        val res=arr.toList
        def priR(xs:List[Int]):List[(Int,Int)]=xs match{
            case Nil=>Nil
            case h::tail=>(h,xs.takeWhile(_==h).length)::priR(xs.dropWhile(_==h))
        }
        priR(res)
    }

P37 (**) Calculate Euler’s totient function phi(m) (improved).
See problem P34 for the definition of Euler’s totient function. If the list of the prime factors of a number m is known in the form of problem P36 then the function phi(m>) can be efficiently calculated as follows: Let [[p1, m1], [p2, m2], [p3, m3], …] be the list of prime factors (and their multiplicities) of a given number m. Then phi(m) can be calculated with the following formula:
phi(m) = (p1-1)p1(m1-1) (p2-1)p2(m2-1) (p3-1)p3(m3-1)
Note that ab stands for the bth power of a.
P38 (*) Compare the two methods of calculating Euler’s totient function.
Use the solutions of problems P34 and P37 to compare the algorithms. Try to calculate phi(10090) as an example.
P39 (*) A list of prime numbers.
Given a range of integers by its lower and upper limit, construct a list of all prime numbers in that range.
scala> listPrimesinRange(7 to 31)
res0: List[Int] = List(7, 11, 13, 17, 19, 23, 29, 31)

    import scala.collection.mutable._
    def listPrimesinRange_39(x:Int,y:Int):List[Int]={
        var res=ArrayBuffer[Int]()
        for(i<- x to  y){
            if(isPrime(i)){
                res+=i
            }
        }
        res.toList
    }

P40 (**) Goldbach’s conjecture.
Goldbach’s conjecture says that every positive even number greater than 2 is the sum of two prime numbers. E.g. 28 = 5 + 23. It is one of the most famous facts in number theory that has not been proved to be correct in the general case. It has been numerically confirmed up to very large numbers (much larger than Scala’s Int can represent). Write a function to find the two prime numbers that sum up to a given even integer.
scala> 28.goldbach
res0: (Int, Int) = (5,23)

    def goldbach_40(x:Int):(Int,Int)={
        val mid=x/2
        for(i<- 1 to mid if(isPrime(i))){
            val re=x-i
            if(isPrime(re)){
                return (i,re)
            }
        }
        (0,0)           
    }

P41 (**) A list of Goldbach compositions.
Given a range of integers by its lower and upper limit, print a list of all even numbers and their Goldbach composition.
scala> printGoldbachList(9 to 20)
10 = 3 + 7
12 = 5 + 7
14 = 3 + 11
16 = 3 + 13
18 = 5 + 13
20 = 3 + 17
In most cases, if an even number is written as the sum of two prime numbers, one of them is very small. Very rarely, the primes are both bigger than, say, 50. Try to find out how many such cases there are in the range 2..3000.
Example (minimum value of 50 for the primes):
scala> printGoldbachListLimited(1 to 2000, 50)
992 = 73 + 919
1382 = 61 + 1321
1856 = 67 + 1789
1928 = 61 + 1867
The file containing the full class for this section is arithmetic.scala.

    def printGoldbachList(x:Int,y:Int)={
        for(i<-x to y){
            if(i%2==0){
                val (a,b)=goldbach_40(i)
                println(i+"="+a+"+"+b)
            }
        }
    }

Logic and Codes
As in the previous section, we will start with a skeleton file, logic1.scala, and add code to it for each problem. The difference here is that the file starts out almost empty.
P46 (**) Truth tables for logical expressions.
Define functions and, or, nand, nor, xor, impl, and equ (for logical equivalence) which return true or false according to the result of their respective operations; e.g. and(A, B) is true if and only if both A and B are true.
scala> and(true, true)
res0: Boolean = true

    def and(x:Boolean,y:Boolean):Boolean=(x,y) match {
        case (_,false) =>false
        case (false,_) =>false
        case _ =>true
    }

scala> xor(true. true)
res1: Boolean = false
def xor(x:Boolean,y:Boolean):Boolean=(x,y) match {
case (false,false) =>false
case (true,true) =>false
case _ =>true
}
A logical expression in two variables can then be written as an function of two variables, e.g: (a: Boolean, b: Boolean) => and(or(a, b), nand(a, b))
Now, write a function called table2 which prints the truth table of a given logical expression in two variables.
scala> table2((a: Boolean, b: Boolean) => and(a, or(a, b)))
A B result
true true true
true false true
false true false
false false false

    def table2_46(f:(Boolean,Boolean)=>Boolean)={
        val de=List(true,false)
        println("A    "+"B    "+"result")
        de foreach(x => de.foreach(y=>println(x+" "+y+" "+f(x,y))))
    }

    def or(x:Boolean,y:Boolean):Boolean=(x,y) match {
        case (false,false) =>false
        case _ =>true
    }

    def xor(x:Boolean,y:Boolean):Boolean=(x,y) match {
        case (false,false) =>false
        case (true,true) =>false
        case _ =>true
    }

    def and(x:Boolean,y:Boolean):Boolean=(x,y) match {
        case (_,false) =>false
        case (false,_) =>false
        case _ =>true
    }

P47 (*) Truth tables for logical expressions (2).
Continue problem P46 by redefining and, or, etc as operators. (i.e. make them methods of a new class with an implicit conversion from Boolean.) not will have to be left as a object method.
scala> table2((a: Boolean, b: Boolean) => a and (a or not(b)))
A B result
true true true
true false true
false true false
false false false
P48 (**) Truth tables for logical expressions (3).
Omitted for now.

object App{
import S47._
class S47(a: Boolean) {
def and(b: Boolean): Boolean = (a, b) match {
case (true, true) => true
case _ => false
}
def or(b: Boolean): Boolean = (a, b) match {
case (true, _) => true
case (_, true) => true
case _ => false
}
def equ(b: Boolean): Boolean = (a and b) or (not(a) and not(b))
def xor(b: Boolean): Boolean = not(a equ b)
def nor(b: Boolean): Boolean = not(a or b)
def nand(b: Boolean): Boolean = not(a and b)
def impl(b: Boolean): Boolean = not(a) or b
}
object S47 {
def not(b:Boolean):Boolean=b match {
case true => false
case false =>true
}
implicit def f(a: Boolean): S47 = new S47(a)
}

def table2_47(f:(Boolean,Boolean)=>Boolean)={
    val de=List(true,false)
    println("A    "+"B    "+"result")
    de foreach(x => de.foreach(y=>println(x+" "+y+" "+f(x,y))))
}

def main(args:Array[String]){
    table2_47((a:Boolean,b:Boolean)=> a and (a or not(b)))
    }

}

P49 (**) Gray code.
An n-bit Gray code is a sequence of n-bit strings constructed according to certain rules. For example,
n = 1: C(1) = (“0”, “1”).
n = 2: C(2) = (“00”, “01”, “11”, “10”).
n = 3: C(3) = (“000”, “001”, “011”, “010”, “110”, “111”, “101”, “100”).
Find out the construction rules and write a function to generate Gray codes.
scala> gray(3)
res0 List[String] = List(000, 001, 011, 010, 110, 111, 101, 100)
See if you can use memoization to make the function more efficient.
def gray_49(x:Int):List[String]={
val n=1<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值