スペルワードに最適なレターカード


15

単語のリストがあり、レターカードを使用して各単語のスペルを確認したいとします。たとえば、catのスペルには、C、A、Tというラベルの付いた3枚のカードを使用します。

各カードが両面であると仮定して、単語リスト全体を綴るのに使用できるカードの最小数を定義するプログラムを提出します。

入力は単語リストであり、ファイルベース、ハードコーディング、コマンドラインなど何でもかまいません。出力は、カードがどのようにラベル付けされているかが明確である限り、適切なフォーマットと順序で並べられたカードのリストです。

大文字と小文字は区別されません。ゴルフ、ゴルフ、ゴルフは同等です。

いくつかのヒント:

  • カードの数は、最長の単語の長さ以上にすることができます
  • カードが両面に同じ文字を持っていることは意味がありません
  • 大文字と小文字は区別されませんが、特定の対称性を活用するには小文字をお勧めします

例、これらは特定の対称性を利用します:

入力:ベン、ボグ、バグ、デン、ドゥ、ドゥ、ドッグ、デュー、ダグ、エド、エンド、ゴブ、ゴッド、ネッド、オーデ、ペン、ポー、パグ

出力:b / d、e / g、o / n

入力:an、and、ape、are、be、bed、bud、bur、dan、deb、dub、ear、ed、era、nap、pan、pea、pub、rae、ran、rub

出力:a / b、d / r、e / n

人気のコンテストにするため、コードの優雅さ、実行時のパフォーマンス、および巧妙さ(ルールの曲げや抜け穴を含む)が重要です!

追加:「許可された」対称性、特殊なフォントを使用できるかどうか、カードを折りたたむことができるかどうかを尋ねる人もいます。

許可される対称性は、0、90、180、または270度の回転後に互いに似ている任意の文字です。これには、b / q、d / p、n / uが含まれます。また、M / W、Z / N、そしてもちろんI / l(大文字のi、小文字のL)と言います。私はおそらく表面をひっかいているので、他に不明な点がある場合は尋ねてください。

シンプルにするために、標準のsans-serifフォント、たとえばSEで使用されているものに制限してください。

折り畳みに関しては、BをD、E、F、I、P、またはRにすることができます。たとえば、本当に創造的に折りたたむと、CまたはLになる可能性があります。 !

私は子供たちと同じようなカードで遊んでいるときにこの問題を思いつきました。私は、片面カードを作成するのがいかに簡単か、両面カードを作成するのがどれほど難しいかを指摘しました。

追加:最も人気のある回答に対して授与される賞金を提供しました。同点の場合は、最初に提出した人に授与されます。

別のヒント:

  • 片面問題を解くと、必要なカードの最小数がわかります(たとえば、片面カード20枚は両面カード10枚以上に変換されます)

追加:わざわざ、私は忙しくて賞金の期限切れを忘れていました。賞金が始まる前に唯一の答えが提出されたため、結局誰にも行きませんでした!ごめんなさい


3
明確にするために、何が許可されていますか?唯一の対称対ですかn/ud/p?何についてb/qm/w?そして、Pカードを2つに折って上半分がDどうなるのでしょうか?
Sp3000 14年

3
1.それらは承認された「対称性」のリストであり、潜在的なループホールであるフォントに基づいて異なる可能性があると思います(文字がすべて同じである、つまりカードが常に/またはそのようなもの)2.「ケースは重要ではない」ので、「N」は「u」で表すことができますか?
デビッドロジャース14年

あなたはあなたの質問を人気コンテストにすることで不正をしていると思います。あなたは人々に創造的であると言うことで創造性を得るのではなく、彼らに困難な挑戦を与え、彼らに彼らができるすべてを絞り出させることでそれを得る。
XNOR

@ sp3000-もちろんb / q。他の質問については、ルールを明確にします。

1
これを人気コンテストとして(賞金は言うまでもありませんが)持っているのは正しくありません。答えが最適であるという保証はありますか?1つの答えは次善の結果が得られますが、いくつかの理由のために、最高の票を持っている...場合はどう
オプティマイザ

回答:


5

C#-CardChooser

概要

このアプリケーションは、ブルートフォースメソッドを使用して各リストを解決しようとします。最初に選択する潜在的なカードのリストを作成し、次に最適なものを決定し(最も文字を削除し、長い単語を最も短くする)、これを結果リストに追加し、十分な潜在的なカードを選択するまでこのプロセスを続行しますリスト内のすべての単語を削除するには、それらのカードを各単語に再照合し、出力を印刷します。

提供されたWindowsフォームアプリケーションをダウンロードして構築せずにこのコードのより限定されたバージョンを表示したい場合は、提供されたリンクを使用して小さなデータセットでプログラムを実行できますが、これはコンソールアプリケーションバージョンであることに注意してくださいカードは回転しません:http : //ideone.com/fork/VD1gJF

改訂履歴

Current-@Zgarbによって提案されたより良い結果最適化を追加しました

更新3-より多くのコードのクリーンアップ、より多くのバグ修正、より良い結果

更新2-Windowsフォーム、より詳細な出力

更新1-キャラクターの対称性の新規/より良いサポート

オリジナル-コンソールアプリケーション

acr、aft、ain、sll、win、say、said、fast、epic 出力0

hes、will、with、wont、will、willve、wouldnt、まだ、あなた、youd、youll 出力1

aaaa、bbbb、cccc
出力2

コード

同じクラスとメソッドをすべて共有するConsoleAppとWindowsFormsコードを使用して、これを1つの大きなプロジェクトに結合し、RunButton_Clickメソッドで異なる領域を分割する必要があります。今のところ、これが私が持っているものです:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CardChooserForms
{
    public partial class CardChooser : Form
    {
        private class Solution : IEquatable<Solution>
        {
            public List<string> Cards { get; set; }
            public List<string> Remaining { get; set; }

            public int RemainingScore
            {
                get
                {
                    return this.Remaining.Sum(b => b.ToCharArray().Count());
                }
            }

            public bool Equals(Solution other)
            {
                return new string(Cards.OrderBy(a => a).SelectMany(a => a).ToArray()) == new string(other.Cards.OrderBy(a => a).SelectMany(a => a).ToArray());
            }

            public override int GetHashCode()
            {
                return (new string(Cards.OrderBy(a => a).SelectMany(a => a).ToArray())).GetHashCode();
            }
        }
        private class Symmetry
        {
            public char Value { get; set; }
            public Int16 RotationDifference { get; set; }
        }

        /// <summary>
        /// This is where Symmetries are stored, right now it only has support for pairs(two values per array)
        /// </summary>
        private static Symmetry[][] _rotatableCharacters = new Symmetry[][] {                 
                new Symmetry[] { new Symmetry {Value = 'Z'}, new Symmetry {Value = 'N', RotationDifference = 90}}, 
                new Symmetry[] { new Symmetry {Value = 'd'}, new Symmetry {Value = 'p', RotationDifference = 180 }}, 
                new Symmetry[] { new Symmetry {Value = 'u'}, new Symmetry {Value = 'n', RotationDifference = 180 }}, 
                new Symmetry[] { new Symmetry {Value = 'm'}, new Symmetry {Value = 'w', RotationDifference = 180 }}, 
                new Symmetry[] { new Symmetry {Value = 'b'}, new Symmetry {Value = 'q', RotationDifference = 180 }}, 
                new Symmetry[] { new Symmetry {Value = 'l'}, new Symmetry {Value = 'I', RotationDifference = 0}},                 
            };

        //These all control the output settings
        private readonly static int _defualtSpacing = 25;
        private readonly static int _defualtFontSize = 8;
        private readonly static Font _defualtFont = new Font("Microsoft Sans Serif", _defualtFontSize);
        private readonly static Brush _defualtBackgroundColor = Brushes.Beige;
        private readonly static Brush _defualtForegroundColor = Brushes.Black;


        public CardChooser()
        {
            InitializeComponent();
        }

        private void RunButton_Click(object sender, EventArgs e)
        {            
            #region Input Parsing
            //Get input                         
            string input = InputRichTextBox.Text;

            if (!input.Contains(","))
                throw new ArgumentException("Input must contain more than one value and must be seprated by commas.");

            //Parse input
            var inputLowercasedTrimedTransformed = input.Split(',').Select(a => a.ToLowerInvariant().Trim()).ToArray();
            var inputSplitTrimIndex = input.Split(',').Select(a => a.Trim()).ToArray().Select((a, index) => new { value = a, index }).ToArray();
            #endregion Input Parsing

            #region Card Formation
            var inputCharParsed = inputLowercasedTrimedTransformed.Select(a => a.ToCharArray()).ToArray();
            var possibleCards = GetAllCasesTwoLengthArrayElements(
                UniqueBiDirection(
                //Get unique characters
                    inputCharParsed
                    .SelectMany(a => a)
                    .Distinct()
                    .Select(a => new
                    {
                        Character = a,
                        PossibleCharacters = inputCharParsed.SelectMany(b => b).Where(b => b != a).ToList()
                    })
                //Now get distinct cards(ie NB == BN, NB != NE)
                    .SelectMany(a => a.PossibleCharacters.Select(b => new string(new char[] { a.Character, b })).ToArray()).ToArray()
                    ).ToArray()
                ).ToArray();

            //Now get every possible character each card can eliminate
            var possibleCharsFromCards = GetAllPossibleCharsFromACards(possibleCards).ToArray();

            //Now set up some possibilities that contain only one card
            var possibleCardCombinations = possibleCards.Select((a, index) => new Solution
            {
                Cards = new List<string> { a },
                //Use the index of each card to reference the possible characters it can remove, then remove them per card to form a initial list of cards
                Remaining = inputLowercasedTrimedTransformed.Select(b => b.RemoveFirstInCharArr(possibleCharsFromCards[index].ToLowerInvariant().ToCharArray())).ToList()
            })
            //Take the best scoring card, discard the rest
            .OrderBy(a => a.RemainingScore)
            .ThenBy(a => a.Remaining.Max(b => b.Length))
            .Take(1).ToList();
            #endregion Card Formation

            #region Card Selection
            //Find best combination by iteratively trying every combination + 1 more card, and choose the lowest scoring one 
            while (!possibleCardCombinations.Any(a => a.Remaining.Sum(b => b.ToCharArray().Count()) == 0) && possibleCardCombinations.First().Cards.Count() < possibleCards.Count())
            {
                //Clear the list each iteration(as you can assume the last generations didn't work
                var newPossibilites = new List<Solution>();
                var currentRoundCardCombinations = possibleCardCombinations.ToArray();
                possibleCardCombinations.Clear();

                foreach (var trySolution in currentRoundCardCombinations)
                    foreach (var card in possibleCards.Select((a, index) => new { value = a, index }).Where(a => !trySolution.Cards.Contains(a.value)).ToArray())
                    {
                        var newSolution = new Solution();
                        newSolution.Cards = trySolution.Cards.ToList();
                        newSolution.Cards.Add(card.value);
                        newSolution.Remaining = trySolution.Remaining.ToList().Select(a => a.RemoveFirstInCharArr(possibleCharsFromCards[card.index].ToLowerInvariant().ToCharArray())).ToList();
                        newPossibilites.Add(newSolution);
                    }

                //Choose the highest scoring card
                possibleCardCombinations = newPossibilites
                    .OrderBy(a => a.RemainingScore)
                    .ThenBy(a => a.Remaining.Max(b => b.Length))
                    .Distinct().Take(1).ToList();
            }
            var finalCardSet = possibleCardCombinations.First().Cards.ToArray();
            #endregion Card Selection

            #region Output
            using (var image = new Bitmap(500, inputSplitTrimIndex.Count() * _defualtSpacing + finalCardSet.Count() * (_defualtFontSize / 2) + _defualtSpacing))
            using (Graphics graphic = Graphics.FromImage(image))
            {
                //Background
                graphic.FillRectangle(_defualtBackgroundColor, 0, 0, image.Width, image.Height);

                //Header                
                graphic.DrawString("Total Number of Cards Required: " + finalCardSet.Count(), _defualtFont, _defualtForegroundColor, new PointF(0, 0));
                graphic.DrawString(
                    "Cards: " + String.Join(", ", finalCardSet.Select(a => a[0] + "/" + a[1])),
                    _defualtFont,
                    _defualtForegroundColor,
                    new RectangleF(0, _defualtSpacing, image.Width - _defualtSpacing, finalCardSet.Count() * 5));

                //Results
                foreach (var element in inputSplitTrimIndex)
                {
                    //Paint the word
                    graphic.DrawString(element.value + " -> ", _defualtFont, _defualtForegroundColor, new PointF(0, element.index * _defualtSpacing + finalCardSet.Count() * (_defualtFontSize / 2) + _defualtSpacing));

                    //Now go through each character, determining the matching card, and wether that card has to be flipped
                    foreach (var card in GetOrderedCardsRequired(inputLowercasedTrimedTransformed[element.index].ToLowerInvariant(), finalCardSet.ToArray()).ToArray().Select((a, index) => new { value = a, index }))
                        using (var tempGraphic = Graphics.FromImage(image))
                        {
                            //For cards that need to flip
                            if (Char.ToUpperInvariant(element.value[card.index]) != Char.ToUpperInvariant(card.value[0]) &&
                                Char.ToUpperInvariant(element.value[card.index]) != Char.ToUpperInvariant(card.value[1]))
                            {
                                //TODO this is hacky and needs to be rethought
                                var rotateAmount = _rotatableCharacters
                                    .OrderByDescending(a => a.Any(b => b.Value == Char.ToLowerInvariant(element.value[card.index])))
                                    .First(a => a.Any(b => Char.ToUpperInvariant(b.Value) == Char.ToUpperInvariant(element.value[card.index])))
                                    [1].RotationDifference;

                                //Rotate
                                tempGraphic.TranslateTransform(
                                    _defualtSpacing * (_defualtFontSize / 2) + card.index * _defualtSpacing + (rotateAmount == 90 ? 0 : _defualtSpacing / 2) + (rotateAmount == 180 ? -(_defualtSpacing / 4) : 0),
                                    finalCardSet.Count() * (_defualtFontSize / 2) + _defualtSpacing + element.index * _defualtSpacing + (rotateAmount == 180 ? 0 : _defualtSpacing / 2));
                                tempGraphic.RotateTransform(rotateAmount);

                                //Print string
                                tempGraphic.DrawString(
                                String.Join("/", card.value.ToCharArray().Select(a => new string(new char[] { a })).ToArray()),
                                _defualtFont,
                                Brushes.Black,
                                new RectangleF(-(_defualtSpacing / 2), -(_defualtSpacing / 2), _defualtSpacing, _defualtSpacing));
                            }
                            else
                                tempGraphic.DrawString(
                                     String.Join("/", card.value.ToCharArray().Select(a => new string(new char[] { a })).ToArray()),
                                     _defualtFont,
                                     _defualtForegroundColor,
                                     new RectangleF(
                                         _defualtSpacing * (_defualtFontSize / 2) + card.index * _defualtSpacing,
                                         finalCardSet.Count() * (_defualtFontSize / 2) + _defualtSpacing + element.index * _defualtSpacing,
                                         _defualtSpacing, _defualtSpacing));
                        }
                }

                OutputPictureBox.Image = new Bitmap(image);
            }
            #endregion Output
        }

        private IEnumerable<string> GetAllPossibleCharsFromACards(string[] cards)
        {
            return cards.Select(a => 
                new string(a.ToCharArray().Concat(_rotatableCharacters
                                    .Where(b => b.Select(c => c.Value).Intersect(a.ToCharArray()).Count() > 0)
                                    .SelectMany(b => b.Select(c => c.Value))
                                    .Distinct().ToArray()).Distinct().ToArray()));
        }

        private IEnumerable<string> GetOrderedCardsRequired(string word, string[] cards)
        {
            var solution = new List<string>();
            var tempCards = GetAllPossibleCharsFromACards(cards).Select((a, index) => new { value = a, index }).ToList();

            foreach (var letter in word.ToCharArray())
            {
                //TODO this still could theoretically fail I think                
                var card = tempCards
                    //Order by the least number of characters match
                    .OrderBy(a => word.ToLowerInvariant().Intersect(a.value.ToLowerInvariant()).Count())
                    .ThenByDescending(a => tempCards.Sum(b => b.value.ToLowerInvariant().Intersect(a.value.ToLowerInvariant()).Count()))
                    //Then take the least useful card for the other parts of the word
                    .First(a => a.value.ToLowerInvariant().Contains(Char.ToLowerInvariant(letter)));
                solution.Add(cards[card.index]);
                tempCards.Remove(card);
            }
            return solution;
        }

        private static IEnumerable<string> UniqueBiDirection(string[] input)
        {
            var results = new List<string>();
            foreach (var element in input)
                if (!results.Any(a => a == new string(element.ToCharArray().Reverse().ToArray()) || a == element))
                    results.Add(element);
            return results;
        }

        private static IEnumerable<string> GetAllCasesTwoLengthArrayElements(string[] input)
        {
            if (input.Any(a => a.Length != 2))
                throw new ArgumentException("This method is only for arrays with two characters");

            List<string> output = input.ToList();
            foreach (var element in input)
            {
                output.Add(new string(new char[] { Char.ToUpperInvariant(element[0]), Char.ToUpperInvariant(element[1]) }));
                output.Add(new string(new char[] { element[0], Char.ToUpperInvariant(element[1]) }));
                output.Add(new string(new char[] { Char.ToUpperInvariant(element[0]), element[1] }));
            }
            return output;
        }

        private void SaveButton_Click(object sender, EventArgs e)
        {
            using (var image = new Bitmap(OutputPictureBox.Image))
                image.Save(Directory.GetCurrentDirectory() + "Output.png", ImageFormat.Png);
        }
    }

    public static class StringExtensions
    {
        public static string RemoveFirstInCharArr(this string source, char[] values)
        {
            var tempSource = source.ToUpperInvariant();
            foreach (var value in values)
            {
                int index = tempSource.IndexOf(Char.ToUpperInvariant(value));
                if (index >= 0) return source.Remove(index, 1);
            }
            return source;
        }        
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CardChooserForms
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new CardChooser());
        }
    }
}


namespace CardChooserForms
{
    partial class CardChooser
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.InputRichTextBox = new System.Windows.Forms.RichTextBox();
            this.EnterInputLabel = new System.Windows.Forms.Label();
            this.RunButton = new System.Windows.Forms.Button();
            this.OutputPictureBox = new System.Windows.Forms.PictureBox();
            this.OutputPanel = new System.Windows.Forms.Panel();
            this.SaveButton = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.OutputPictureBox)).BeginInit();
            this.OutputPanel.SuspendLayout();
            this.SuspendLayout();
            // 
            // InputRichTextBox
            // 
            this.InputRichTextBox.Location = new System.Drawing.Point(60, 40);
            this.InputRichTextBox.Name = "InputRichTextBox";
            this.InputRichTextBox.Size = new System.Drawing.Size(400, 100);
            this.InputRichTextBox.TabIndex = 0;
            this.InputRichTextBox.Text = "";
            // 
            // EnterInputLabel
            // 
            this.EnterInputLabel.AutoSize = true;
            this.EnterInputLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.EnterInputLabel.Location = new System.Drawing.Point(57, 20);
            this.EnterInputLabel.Name = "EnterInputLabel";
            this.EnterInputLabel.Size = new System.Drawing.Size(81, 17);
            this.EnterInputLabel.TabIndex = 1;
            this.EnterInputLabel.Text = "Enter Input:";
            // 
            // RunButton
            // 
            this.RunButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.RunButton.Location = new System.Drawing.Point(60, 147);
            this.RunButton.Name = "RunButton";
            this.RunButton.Size = new System.Drawing.Size(180, 52);
            this.RunButton.TabIndex = 2;
            this.RunButton.Text = "Run";
            this.RunButton.UseVisualStyleBackColor = true;
            this.RunButton.Click += new System.EventHandler(this.RunButton_Click);
            // 
            // OutputPictureBox
            // 
            this.OutputPictureBox.Location = new System.Drawing.Point(3, 3);
            this.OutputPictureBox.Name = "OutputPictureBox";
            this.OutputPictureBox.Size = new System.Drawing.Size(500, 500);
            this.OutputPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
            this.OutputPictureBox.TabIndex = 3;
            this.OutputPictureBox.TabStop = false;
            // 
            // OutputPanel
            // 
            this.OutputPanel.AutoScroll = true;
            this.OutputPanel.Controls.Add(this.OutputPictureBox);
            this.OutputPanel.Location = new System.Drawing.Point(4, 205);
            this.OutputPanel.Name = "OutputPanel";
            this.OutputPanel.Size = new System.Drawing.Size(520, 520);
            this.OutputPanel.TabIndex = 4;
            // 
            // SaveButton
            // 
            this.SaveButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.SaveButton.Location = new System.Drawing.Point(280, 147);
            this.SaveButton.Name = "SaveButton";
            this.SaveButton.Size = new System.Drawing.Size(180, 52);
            this.SaveButton.TabIndex = 5;
            this.SaveButton.Text = "Save";
            this.SaveButton.UseVisualStyleBackColor = true;
            this.SaveButton.Click += new System.EventHandler(this.SaveButton_Click);
            // 
            // CardChooser
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(534, 737);
            this.Controls.Add(this.SaveButton);
            this.Controls.Add(this.RunButton);
            this.Controls.Add(this.EnterInputLabel);
            this.Controls.Add(this.InputRichTextBox);
            this.Controls.Add(this.OutputPanel);
            this.Name = "CardChooser";
            this.Text = "Card Chooser";
            ((System.ComponentModel.ISupportInitialize)(this.OutputPictureBox)).EndInit();
            this.OutputPanel.ResumeLayout(false);
            this.OutputPanel.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.RichTextBox InputRichTextBox;
        private System.Windows.Forms.Label EnterInputLabel;
        private System.Windows.Forms.Button RunButton;
        private System.Windows.Forms.PictureBox OutputPictureBox;
        private System.Windows.Forms.Panel OutputPanel;
        private System.Windows.Forms.Button SaveButton;
    }
}

1
iカードなしでどのように「可能性」を綴りますか?
クラウディ14年

「もちろんのI /リットル(資本I、小文字のL)」、小文字のlは資本I.静置する必要がありますので
デヴィッド・ロジャース

ああ、あなたが出力にそれを指定する必要がありそうです
クラウディウ

@Claudiuええ、私はしばらくの間、これは本当に私がYimin Rongに尋ねた2番目の質問に帰着し、彼がそれを正しく明確にしたと思います、カードに「l」を出力した場合、大文字のIと下のLの両方に使用できます。大文字と小文字が完全に一致しない出力になりますが、質問の条件を満たしているため「OK」だと思いますが、ここでも開いています...必要に応じて明確に、多分それ以降のバージョンでは、私は文字で出力結果生成された文字列を回転させることができますまたはそのような何か
デヴィッド・ロジャース

間違いがあると思います。saidの最後の文字がWまたはpではない
誇りに思っているhaskeller 14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.