Skip to content

Commit

Permalink
Solve the "Test for palindromic permutations" problem
Browse files Browse the repository at this point in the history
  • Loading branch information
mrekucci committed Nov 11, 2015
1 parent fe85b00 commit aa350bb
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ Hash Tables
| Problem | Test | Implemented |
|--------------------------------------------------------------------------|:------------:|:-----------:|
| [Partition into anagrams][212] | [tests][213] ||
| [Test for palindromic permutations][214] | [tests][215] | |
| [Test for palindromic permutations][214] | [tests][215] | |
| [Is an anonymous letter constructible?][216] | [tests][217] | |
| [Implement an ISBN cache][218] | [tests][219] | |
| [Compute the LCA, optimizing for close ancestors][220] | [tests][221] | |
Expand Down Expand Up @@ -617,8 +617,8 @@ Honors Class
[211]: in_progress.md
[212]: htables/anagram.go
[213]: htables/anagram_test.go
[214]: in_progress.md
[215]: in_progress.md
[214]: htables/palindrom.go
[215]: htables/palindrom_test.go
[216]: in_progress.md
[217]: in_progress.md
[218]: in_progress.md
Expand Down
29 changes: 29 additions & 0 deletions htables/palindrom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2015, Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.txt file.

package htables

// CanFormPalindrome returns true if s can represent a palindrome.
// The time complexity is O(n) and O(c) additional space is needed, where
// c is the number of distinct characters in the string s.
func CanFormPalindrome(s string) bool {
if len(s) == 0 {
return true
}

f := make(map[rune]int)
for _, c := range s {
f[c]++
}

var odd int
for _, cnt := range f {
if cnt%2 != 0 {
if odd++; odd != 1 {
return false
}
}
}
return true
}
46 changes: 46 additions & 0 deletions htables/palindrom_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2015, Peter Mrekaj. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE.txt file.

package htables

import (
"math/rand"
"testing"

"github.com/mrekucci/epi/internal/epiutil"
)

func TestCanFormPalindrome(t *testing.T) {
for _, test := range []struct {
in string
want bool
}{
{"", true},
{"ab", false},
{"aab", true},
{"aaab", false},
{"aaabccc", false},
{"aaabcc", false},
{"edified", true},
{"界☺世", false},
{"世世☺", true},
} {
if got := CanFormPalindrome(test.in); got != test.want {
t.Errorf("CanFormPalindrome(%q) = %t; want %t", test.in, got, test.want)
}
}
}

func benchCanFormPalindrome(b *testing.B, size int) {
b.StopTimer()
s := epiutil.RandStr(size, "abcdefghijklmnopqrstuvwxyz", rand.NewSource(int64(size)))
b.StartTimer()
for i := 0; i < b.N; i++ {
CanFormPalindrome(s)
}
}

func BenchmarkCanFormPalindrome1e2(b *testing.B) { benchCanFormPalindrome(b, 1e2) }
func BenchmarkCanFormPalindrome1e4(b *testing.B) { benchCanFormPalindrome(b, 1e4) }
func BenchmarkCanFormPalindrome1e6(b *testing.B) { benchCanFormPalindrome(b, 1e6) }

0 comments on commit aa350bb

Please sign in to comment.